diff --git a/coverage.html b/coverage.html new file mode 100644 index 0000000000..31f1f9cd62 --- /dev/null +++ b/coverage.html @@ -0,0 +1,4627 @@ + + + + + + feast: Go Coverage Report + + + +
+ +
+ not tracked + + not covered + covered + +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + diff --git a/coverage.out b/coverage.out new file mode 100644 index 0000000000..197c71b8a5 --- /dev/null +++ b/coverage.out @@ -0,0 +1,950 @@ +mode: set +github.com/feast-dev/feast/go/types/typeconversion.go:13.72,14.23 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:17.2,17.27 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:14.23,16.3 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:18.29,19.39 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:20.30,21.39 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:22.29,23.41 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:24.29,25.41 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:26.29,27.43 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:28.30,29.43 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:30.28,31.44 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:32.32,33.58 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:34.34,35.53 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:36.33,37.53 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:38.33,39.55 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:40.33,41.55 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:42.33,43.57 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:44.34,45.57 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:46.37,47.48 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:48.41,49.62 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:50.10,52.85 1 0 +github.com/feast-dev/feast/go/types/typeconversion.go:56.79,57.11 1 0 +github.com/feast-dev/feast/go/types/typeconversion.go:58.29,59.39 1 0 +github.com/feast-dev/feast/go/types/typeconversion.go:60.30,61.39 1 0 +github.com/feast-dev/feast/go/types/typeconversion.go:62.29,63.41 1 0 +github.com/feast-dev/feast/go/types/typeconversion.go:64.29,65.41 1 0 +github.com/feast-dev/feast/go/types/typeconversion.go:66.29,67.43 1 0 +github.com/feast-dev/feast/go/types/typeconversion.go:68.30,69.43 1 0 +github.com/feast-dev/feast/go/types/typeconversion.go:70.28,71.44 1 0 +github.com/feast-dev/feast/go/types/typeconversion.go:72.33,73.58 1 0 +github.com/feast-dev/feast/go/types/typeconversion.go:74.35,75.53 1 0 +github.com/feast-dev/feast/go/types/typeconversion.go:76.34,77.53 1 0 +github.com/feast-dev/feast/go/types/typeconversion.go:78.34,79.55 1 0 +github.com/feast-dev/feast/go/types/typeconversion.go:80.34,81.55 1 0 +github.com/feast-dev/feast/go/types/typeconversion.go:82.34,83.57 1 0 +github.com/feast-dev/feast/go/types/typeconversion.go:84.35,85.57 1 0 +github.com/feast-dev/feast/go/types/typeconversion.go:86.38,87.48 1 0 +github.com/feast-dev/feast/go/types/typeconversion.go:88.43,89.62 1 0 +github.com/feast-dev/feast/go/types/typeconversion.go:90.10,92.85 1 0 +github.com/feast-dev/feast/go/types/typeconversion.go:96.86,97.31 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:163.2,163.12 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:97.31,98.39 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:103.3,103.41 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:98.39,100.12 2 1 +github.com/feast-dev/feast/go/types/typeconversion.go:105.30,106.43 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:107.29,108.44 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:109.29,110.45 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:111.28,112.44 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:113.28,114.44 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:115.30,116.44 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:117.30,118.45 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:119.32,120.69 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:121.27,124.62 2 1 +github.com/feast-dev/feast/go/types/typeconversion.go:159.11,160.63 1 0 +github.com/feast-dev/feast/go/types/typeconversion.go:126.31,127.55 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:130.30,131.56 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:134.30,135.57 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:138.29,139.56 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:142.29,143.56 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:146.31,147.56 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:150.31,151.57 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:154.33,155.64 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:127.55,129.6 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:131.56,133.6 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:135.57,137.6 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:139.56,141.6 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:143.56,145.6 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:147.56,149.6 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:151.57,153.6 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:155.64,157.6 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:166.72,169.42 2 1 +github.com/feast-dev/feast/go/types/typeconversion.go:243.2,243.24 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:316.2,316.20 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:169.42,173.44 4 1 +github.com/feast-dev/feast/go/types/typeconversion.go:240.3,240.21 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:173.44,174.33 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:237.4,237.27 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:175.36,177.46 2 1 +github.com/feast-dev/feast/go/types/typeconversion.go:180.5,181.94 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:182.36,184.46 2 1 +github.com/feast-dev/feast/go/types/typeconversion.go:187.5,188.94 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:189.38,191.46 2 1 +github.com/feast-dev/feast/go/types/typeconversion.go:194.5,195.94 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:196.38,198.46 2 1 +github.com/feast-dev/feast/go/types/typeconversion.go:201.5,202.97 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:203.34,205.46 2 1 +github.com/feast-dev/feast/go/types/typeconversion.go:208.5,209.94 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:210.34,212.46 2 1 +github.com/feast-dev/feast/go/types/typeconversion.go:215.5,216.97 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:217.39,219.46 2 1 +github.com/feast-dev/feast/go/types/typeconversion.go:222.5,223.91 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:224.43,226.46 2 1 +github.com/feast-dev/feast/go/types/typeconversion.go:230.5,232.59 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:177.46,179.6 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:184.46,186.6 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:191.46,193.6 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:198.46,200.6 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:205.46,207.6 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:212.46,214.6 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:219.46,221.6 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:226.46,228.6 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:244.34,245.40 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:252.34,253.40 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:260.36,261.40 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:268.36,269.40 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:276.37,277.40 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:284.32,285.40 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:292.32,293.40 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:300.41,301.40 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:308.18,309.40 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:312.10,313.94 1 0 +github.com/feast-dev/feast/go/types/typeconversion.go:245.40,246.23 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:246.23,248.5 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:248.10,250.5 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:253.40,254.23 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:254.23,256.5 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:256.10,258.5 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:261.40,262.23 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:262.23,264.5 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:264.10,266.5 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:269.40,270.23 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:270.23,272.5 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:272.10,274.5 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:277.40,278.23 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:278.23,280.5 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:280.10,282.5 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:285.40,286.23 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:286.23,288.5 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:288.10,290.5 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:293.40,294.23 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:294.23,296.5 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:296.10,298.5 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:301.40,302.23 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:302.23,304.5 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:304.10,306.5 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:309.40,311.4 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:319.125,323.34 3 1 +github.com/feast-dev/feast/go/types/typeconversion.go:335.2,335.22 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:323.34,324.17 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:324.17,326.18 2 1 +github.com/feast-dev/feast/go/types/typeconversion.go:329.4,329.24 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:326.18,328.5 1 0 +github.com/feast-dev/feast/go/types/typeconversion.go:329.24,330.10 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:335.22,338.17 3 1 +github.com/feast-dev/feast/go/types/typeconversion.go:342.3,342.33 1 1 +github.com/feast-dev/feast/go/types/typeconversion.go:338.17,340.4 1 0 +github.com/feast-dev/feast/go/types/typeconversion.go:343.8,345.3 1 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/filelogsink.go:25.56,26.16 1 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/filelogsink.go:30.2,31.16 2 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/filelogsink.go:34.2,34.41 1 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/filelogsink.go:26.16,28.3 1 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/filelogsink.go:31.16,33.3 1 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/filelogsink.go:37.59,42.16 4 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/filelogsink.go:45.2,49.64 4 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/filelogsink.go:42.16,44.3 1 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/filelogsink.go:52.62,55.2 1 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/logger.go:70.76,75.2 1 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/logger.go:77.129,79.16 2 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/logger.go:82.2,98.20 3 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/logger.go:79.16,81.3 1 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/logger.go:101.46,102.9 1 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/logger.go:103.22,104.13 1 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/logger.go:105.42,106.152 1 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/logger.go:110.40,111.12 1 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/logger.go:111.12,112.7 1 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/logger.go:112.7,113.41 1 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/logger.go:122.4,122.10 1 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/logger.go:113.41,118.13 3 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/logger.go:129.48,130.15 1 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/logger.go:141.2,144.6 3 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/logger.go:180.2,188.12 7 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/logger.go:130.15,132.31 1 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/logger.go:132.31,134.11 2 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/logger.go:137.4,137.33 1 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/logger.go:134.11,136.5 1 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/logger.go:144.6,147.10 2 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/logger.go:175.3,175.17 1 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/logger.go:148.21,150.18 2 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/logger.go:153.4,154.18 2 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/logger.go:157.4,157.21 1 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/logger.go:158.24,160.18 2 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/logger.go:163.24,165.18 2 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/logger.go:168.29,170.18 2 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/logger.go:150.18,152.5 1 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/logger.go:154.18,156.5 1 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/logger.go:160.18,162.5 1 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/logger.go:165.18,167.5 1 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/logger.go:170.18,172.5 1 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/logger.go:175.17,176.9 1 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/logger.go:192.29,193.9 1 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/logger.go:194.25,194.25 0 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/logger.go:195.10,195.10 0 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/logger.go:199.41,202.19 3 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/logger.go:202.19,204.3 1 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/logger.go:207.76,209.2 1 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/logger.go:211.240,212.30 1 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/logger.go:216.2,216.42 1 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/logger.go:220.2,225.38 4 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/logger.go:229.2,229.46 1 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/logger.go:282.2,282.12 1 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/logger.go:212.30,214.3 1 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/logger.go:216.42,218.3 1 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/logger.go:225.38,227.3 1 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/logger.go:229.46,234.51 4 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/logger.go:248.3,249.47 2 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/logger.go:257.3,258.55 2 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/logger.go:266.3,278.17 3 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/logger.go:234.51,236.11 2 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/logger.go:243.4,245.77 3 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/logger.go:236.11,239.12 3 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/logger.go:239.12,241.6 1 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/logger.go:249.47,251.11 2 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/logger.go:254.4,254.40 1 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/logger.go:251.11,253.5 1 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/logger.go:258.55,260.11 2 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/logger.go:263.4,263.45 1 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/logger.go:260.11,262.5 1 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/logger.go:278.17,280.4 1 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/logger.go:287.245,289.2 1 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/memorybuffer.go:29.75,31.16 2 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/memorybuffer.go:34.2,39.8 1 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/memorybuffer.go:31.16,33.3 1 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/memorybuffer.go:44.55,45.21 1 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/memorybuffer.go:52.2,52.25 1 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/memorybuffer.go:56.2,57.16 2 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/memorybuffer.go:61.2,62.12 2 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/memorybuffer.go:45.21,47.17 2 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/memorybuffer.go:47.17,49.4 1 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/memorybuffer.go:52.25,54.3 1 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/memorybuffer.go:57.16,59.3 1 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/memorybuffer.go:65.47,68.32 2 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/memorybuffer.go:72.2,72.12 1 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/memorybuffer.go:68.32,70.3 1 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/memorybuffer.go:75.40,77.16 2 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/memorybuffer.go:80.2,82.12 3 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/memorybuffer.go:77.16,79.3 1 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/memorybuffer.go:85.74,88.42 2 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/memorybuffer.go:97.2,97.50 1 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/memorybuffer.go:106.2,106.46 1 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/memorybuffer.go:121.2,125.42 4 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/memorybuffer.go:88.42,90.17 2 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/memorybuffer.go:94.3,94.71 1 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/memorybuffer.go:90.17,92.4 1 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/memorybuffer.go:97.50,99.17 2 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/memorybuffer.go:103.3,103.76 1 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/memorybuffer.go:99.17,101.4 1 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/memorybuffer.go:106.46,108.17 2 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/memorybuffer.go:112.3,118.38 3 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/memorybuffer.go:108.17,110.4 1 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/memorybuffer.go:131.69,137.49 5 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/memorybuffer.go:141.2,146.37 4 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/memorybuffer.go:181.2,181.46 1 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/memorybuffer.go:189.2,189.33 1 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/memorybuffer.go:137.49,139.3 1 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/memorybuffer.go:146.37,147.50 1 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/memorybuffer.go:153.3,153.58 1 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/memorybuffer.go:159.3,159.54 1 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/memorybuffer.go:173.3,178.102 5 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/memorybuffer.go:147.50,148.38 1 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/memorybuffer.go:151.4,151.57 1 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/memorybuffer.go:148.38,150.5 1 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/memorybuffer.go:153.58,154.43 1 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/memorybuffer.go:157.4,157.62 1 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/memorybuffer.go:154.43,156.5 1 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/memorybuffer.go:159.54,160.42 1 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/memorybuffer.go:163.4,170.107 6 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/memorybuffer.go:160.42,162.5 1 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/memorybuffer.go:181.46,184.17 3 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/memorybuffer.go:184.17,186.4 1 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/offlinestoresink.go:25.94,30.2 1 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/offlinestoresink.go:32.68,33.24 1 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/offlinestoresink.go:36.2,37.16 2 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/offlinestoresink.go:40.2,41.26 2 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/offlinestoresink.go:33.24,35.3 1 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/offlinestoresink.go:37.16,39.3 1 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/offlinestoresink.go:44.64,47.16 3 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/offlinestoresink.go:51.2,53.16 3 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/offlinestoresink.go:56.2,60.65 4 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/offlinestoresink.go:47.16,49.3 1 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/offlinestoresink.go:53.16,55.3 1 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/offlinestoresink.go:63.67,64.24 1 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/offlinestoresink.go:68.2,71.12 3 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/offlinestoresink.go:79.2,79.12 1 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/offlinestoresink.go:64.24,66.3 1 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/offlinestoresink.go:71.12,73.19 2 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/offlinestoresink.go:76.3,76.27 1 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/offlinestoresink.go:73.19,75.4 1 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/service.go:52.104,53.20 1 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/service.go:57.2,63.8 1 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/service.go:53.20,55.3 1 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/service.go:66.98,67.54 1 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/service.go:71.2,71.41 1 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/service.go:75.2,79.54 3 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/service.go:83.2,83.19 1 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/service.go:87.2,89.16 3 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/service.go:93.2,94.16 2 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/service.go:97.2,99.20 2 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/service.go:67.54,69.3 1 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/service.go:71.41,73.3 1 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/service.go:79.54,81.3 1 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/service.go:83.19,85.3 1 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/service.go:89.16,91.3 1 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/service.go:94.16,96.3 1 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/service.go:102.33,103.35 1 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/service.go:103.35,106.3 2 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/featureserviceschema.go:20.114,22.16 2 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/featureserviceschema.go:26.2,27.16 2 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/featureserviceschema.go:31.2,31.66 1 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/featureserviceschema.go:22.16,24.3 1 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/featureserviceschema.go:27.16,29.3 1 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/featureserviceschema.go:34.210,45.63 8 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/featureserviceschema.go:86.2,95.20 2 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/featureserviceschema.go:45.63,49.43 2 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/featureserviceschema.go:49.43,50.49 1 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/featureserviceschema.go:55.4,55.50 1 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/featureserviceschema.go:50.49,54.5 3 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/featureserviceschema.go:55.50,57.80 2 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/featureserviceschema.go:63.5,63.43 1 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/featureserviceschema.go:67.5,68.54 2 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/featureserviceschema.go:57.80,59.6 1 0 +github.com/feast-dev/feast/go/internal/feast/server/logging/featureserviceschema.go:59.11,61.6 1 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/featureserviceschema.go:63.43,65.6 1 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/featureserviceschema.go:70.9,70.54 1 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/featureserviceschema.go:70.54,71.49 1 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/featureserviceschema.go:76.4,76.66 1 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/featureserviceschema.go:71.49,75.5 3 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/featureserviceschema.go:76.66,79.5 2 1 +github.com/feast-dev/feast/go/internal/feast/server/logging/featureserviceschema.go:80.9,83.4 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/http.go:28.46,30.2 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/http.go:32.95,48.47 3 0 +github.com/feast-dev/feast/go/internal/feast/registry/http.go:52.2,52.17 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/http.go:48.47,50.3 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/http.go:55.56,57.16 2 0 +github.com/feast-dev/feast/go/internal/feast/registry/http.go:60.2,62.38 2 0 +github.com/feast-dev/feast/go/internal/feast/registry/http.go:66.2,66.12 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/http.go:57.16,59.3 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/http.go:62.38,64.3 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/http.go:69.81,71.16 2 1 +github.com/feast-dev/feast/go/internal/feast/registry/http.go:75.2,79.16 4 1 +github.com/feast-dev/feast/go/internal/feast/registry/http.go:83.2,83.38 1 1 +github.com/feast-dev/feast/go/internal/feast/registry/http.go:87.2,87.18 1 1 +github.com/feast-dev/feast/go/internal/feast/registry/http.go:71.16,73.3 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/http.go:79.16,81.3 1 1 +github.com/feast-dev/feast/go/internal/feast/registry/http.go:83.38,85.3 1 1 +github.com/feast-dev/feast/go/internal/feast/registry/http.go:90.105,92.16 2 1 +github.com/feast-dev/feast/go/internal/feast/registry/http.go:95.2,98.16 3 1 +github.com/feast-dev/feast/go/internal/feast/registry/http.go:102.2,102.49 1 1 +github.com/feast-dev/feast/go/internal/feast/registry/http.go:106.2,106.12 1 1 +github.com/feast-dev/feast/go/internal/feast/registry/http.go:92.16,94.3 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/http.go:98.16,100.3 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/http.go:102.49,104.3 1 1 +github.com/feast-dev/feast/go/internal/feast/registry/http.go:109.73,111.61 2 1 +github.com/feast-dev/feast/go/internal/feast/registry/http.go:111.61,113.60 2 1 +github.com/feast-dev/feast/go/internal/feast/registry/http.go:116.3,116.42 1 1 +github.com/feast-dev/feast/go/internal/feast/registry/http.go:119.3,120.13 2 1 +github.com/feast-dev/feast/go/internal/feast/registry/http.go:113.60,115.4 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/http.go:116.42,118.4 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/http.go:124.76,126.61 2 1 +github.com/feast-dev/feast/go/internal/feast/registry/http.go:126.61,128.65 2 1 +github.com/feast-dev/feast/go/internal/feast/registry/http.go:131.3,131.50 1 1 +github.com/feast-dev/feast/go/internal/feast/registry/http.go:134.3,135.13 2 1 +github.com/feast-dev/feast/go/internal/feast/registry/http.go:128.65,130.4 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/http.go:131.50,133.4 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/http.go:139.77,141.61 2 1 +github.com/feast-dev/feast/go/internal/feast/registry/http.go:141.61,143.66 2 1 +github.com/feast-dev/feast/go/internal/feast/registry/http.go:146.3,146.52 1 1 +github.com/feast-dev/feast/go/internal/feast/registry/http.go:149.3,150.13 2 1 +github.com/feast-dev/feast/go/internal/feast/registry/http.go:143.66,145.4 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/http.go:146.52,148.4 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/http.go:154.85,156.61 2 1 +github.com/feast-dev/feast/go/internal/feast/registry/http.go:156.61,158.69 2 1 +github.com/feast-dev/feast/go/internal/feast/registry/http.go:161.3,162.13 2 1 +github.com/feast-dev/feast/go/internal/feast/registry/http.go:158.69,160.4 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/http.go:166.80,168.61 2 1 +github.com/feast-dev/feast/go/internal/feast/registry/http.go:168.61,170.69 2 1 +github.com/feast-dev/feast/go/internal/feast/registry/http.go:173.3,174.13 2 1 +github.com/feast-dev/feast/go/internal/feast/registry/http.go:170.69,172.4 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/http.go:178.72,182.50 2 1 +github.com/feast-dev/feast/go/internal/feast/registry/http.go:186.2,186.53 1 1 +github.com/feast-dev/feast/go/internal/feast/registry/http.go:190.2,190.54 1 1 +github.com/feast-dev/feast/go/internal/feast/registry/http.go:194.2,194.62 1 1 +github.com/feast-dev/feast/go/internal/feast/registry/http.go:198.2,198.57 1 1 +github.com/feast-dev/feast/go/internal/feast/registry/http.go:202.2,202.23 1 1 +github.com/feast-dev/feast/go/internal/feast/registry/http.go:182.50,184.3 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/http.go:186.53,188.3 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/http.go:190.54,192.3 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/http.go:194.62,196.3 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/http.go:198.57,200.3 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/http.go:205.74,207.2 1 1 +github.com/feast-dev/feast/go/internal/feast/registry/http.go:209.46,211.2 1 1 +github.com/feast-dev/feast/go/internal/feast/registry/local.go:22.87,25.34 3 0 +github.com/feast-dev/feast/go/internal/feast/registry/local.go:30.2,30.12 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/local.go:25.34,27.3 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/local.go:27.8,29.3 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/local.go:34.72,37.16 3 0 +github.com/feast-dev/feast/go/internal/feast/registry/local.go:40.2,40.54 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/local.go:43.2,43.22 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/local.go:37.16,39.3 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/local.go:40.54,42.3 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/local.go:46.74,48.2 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/local.go:50.46,52.2 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/local.go:54.68,58.16 4 0 +github.com/feast-dev/feast/go/internal/feast/registry/local.go:61.2,62.16 2 0 +github.com/feast-dev/feast/go/internal/feast/registry/local.go:65.2,65.12 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/local.go:58.16,60.3 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/local.go:62.16,64.3 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:45.102,53.33 4 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:67.2,67.15 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:53.33,55.17 2 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:58.3,58.34 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:55.17,57.4 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:59.8,61.17 2 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:64.3,64.34 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:61.17,63.4 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:70.47,72.16 2 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:80.2,81.12 2 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:72.16,73.56 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:77.3,78.53 2 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:73.56,76.4 2 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:84.48,86.25 2 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:86.25,88.17 2 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:88.17,90.4 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:94.36,97.2 2 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:99.63,101.14 2 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:104.2,105.16 2 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:108.2,109.27 2 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:101.14,103.3 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:105.16,107.3 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:112.50,127.2 14 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:129.58,131.34 2 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:131.34,132.48 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:135.3,135.57 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:132.48,134.4 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:139.65,141.49 2 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:141.49,142.55 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:145.3,145.80 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:142.55,144.4 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:149.62,151.43 2 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:151.43,152.52 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:155.3,155.71 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:152.52,154.4 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:159.68,161.55 2 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:161.55,162.58 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:165.3,165.89 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:162.58,164.4 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:169.70,171.59 2 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:171.59,172.60 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:175.3,175.95 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:172.60,174.4 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:184.74,187.58 3 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:187.58,189.3 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:189.8,192.46 3 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:196.3,196.23 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:192.46,195.4 2 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:205.83,208.66 3 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:208.66,210.3 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:210.8,213.55 3 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:217.3,217.27 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:213.55,216.4 2 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:226.89,229.78 3 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:229.78,231.3 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:231.8,234.67 3 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:238.3,238.33 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:234.67,237.4 2 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:247.89,250.72 3 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:250.72,252.3 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:252.8,255.61 3 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:259.3,259.30 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:255.61,258.4 2 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:268.99,271.82 3 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:271.82,273.3 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:273.8,276.71 3 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:280.3,280.35 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:276.71,279.4 2 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:284.81,287.58 3 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:287.58,289.3 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:289.8,290.52 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:290.52,292.4 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:292.9,294.4 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:298.96,301.66 3 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:301.66,303.3 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:303.8,304.71 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:304.71,306.4 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:306.9,308.4 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:312.108,315.78 3 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:315.78,317.3 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:317.8,318.89 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:318.89,320.4 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:320.9,322.4 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:326.105,329.72 3 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:329.72,331.3 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:331.8,332.80 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:332.80,334.4 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:334.9,336.4 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:340.120,343.82 3 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:343.82,345.3 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:345.8,346.95 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:346.95,348.4 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:348.9,350.4 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:354.142,356.16 2 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:359.2,359.78 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:362.2,362.135 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:356.16,358.3 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:359.78,361.3 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:365.145,366.27 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:372.2,372.118 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:367.27,368.61 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/registry.go:369.27,370.55 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/repoconfig.go:49.78,51.68 2 1 +github.com/feast-dev/feast/go/internal/feast/registry/repoconfig.go:54.2,55.16 2 1 +github.com/feast-dev/feast/go/internal/feast/registry/repoconfig.go:58.2,59.21 2 1 +github.com/feast-dev/feast/go/internal/feast/registry/repoconfig.go:51.68,53.3 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/repoconfig.go:55.16,57.3 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/repoconfig.go:64.66,66.16 2 1 +github.com/feast-dev/feast/go/internal/feast/registry/repoconfig.go:69.2,70.16 2 1 +github.com/feast-dev/feast/go/internal/feast/registry/repoconfig.go:74.2,77.74 3 1 +github.com/feast-dev/feast/go/internal/feast/registry/repoconfig.go:80.2,81.21 2 1 +github.com/feast-dev/feast/go/internal/feast/registry/repoconfig.go:66.16,68.3 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/repoconfig.go:70.16,72.3 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/repoconfig.go:77.74,79.3 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/repoconfig.go:84.75,86.94 2 1 +github.com/feast-dev/feast/go/internal/feast/registry/repoconfig.go:109.2,109.29 1 1 +github.com/feast-dev/feast/go/internal/feast/registry/repoconfig.go:86.94,88.39 2 1 +github.com/feast-dev/feast/go/internal/feast/registry/repoconfig.go:88.39,89.13 1 1 +github.com/feast-dev/feast/go/internal/feast/registry/repoconfig.go:90.26,91.33 1 1 +github.com/feast-dev/feast/go/internal/feast/registry/repoconfig.go:94.35,95.33 1 1 +github.com/feast-dev/feast/go/internal/feast/registry/repoconfig.go:98.39,99.33 1 1 +github.com/feast-dev/feast/go/internal/feast/registry/repoconfig.go:102.31,103.33 1 1 +github.com/feast-dev/feast/go/internal/feast/registry/repoconfig.go:91.33,93.6 1 1 +github.com/feast-dev/feast/go/internal/feast/registry/repoconfig.go:95.33,97.6 1 1 +github.com/feast-dev/feast/go/internal/feast/registry/repoconfig.go:99.33,101.6 1 1 +github.com/feast-dev/feast/go/internal/feast/registry/repoconfig.go:103.33,105.6 1 1 +github.com/feast-dev/feast/go/internal/feast/registry/repoconfig.go:112.67,113.70 1 1 +github.com/feast-dev/feast/go/internal/feast/registry/repoconfig.go:113.70,115.39 2 1 +github.com/feast-dev/feast/go/internal/feast/registry/repoconfig.go:145.3,145.30 1 1 +github.com/feast-dev/feast/go/internal/feast/registry/repoconfig.go:115.39,116.13 1 1 +github.com/feast-dev/feast/go/internal/feast/registry/repoconfig.go:117.16,118.36 1 1 +github.com/feast-dev/feast/go/internal/feast/registry/repoconfig.go:121.31,122.36 1 1 +github.com/feast-dev/feast/go/internal/feast/registry/repoconfig.go:125.21,126.36 1 1 +github.com/feast-dev/feast/go/internal/feast/registry/repoconfig.go:129.29,131.30 1 1 +github.com/feast-dev/feast/go/internal/feast/registry/repoconfig.go:118.36,120.6 1 1 +github.com/feast-dev/feast/go/internal/feast/registry/repoconfig.go:122.36,124.6 1 1 +github.com/feast-dev/feast/go/internal/feast/registry/repoconfig.go:126.36,128.6 1 1 +github.com/feast-dev/feast/go/internal/feast/registry/repoconfig.go:132.18,133.51 1 1 +github.com/feast-dev/feast/go/internal/feast/registry/repoconfig.go:134.14,135.51 1 1 +github.com/feast-dev/feast/go/internal/feast/registry/repoconfig.go:136.16,137.51 1 1 +github.com/feast-dev/feast/go/internal/feast/registry/repoconfig.go:138.16,139.44 1 1 +github.com/feast-dev/feast/go/internal/feast/registry/repoconfig.go:140.13,141.73 1 0 +github.com/feast-dev/feast/go/internal/feast/registry/repoconfig.go:146.8,148.3 1 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:72.123,77.63 3 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:119.2,120.51 2 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:124.2,124.34 1 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:77.63,81.50 2 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:81.50,83.18 2 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:86.4,86.74 1 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:93.4,93.55 1 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:83.18,85.5 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:86.74,91.5 1 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:93.55,97.5 1 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:99.9,99.67 1 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:99.67,101.18 2 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:104.4,109.18 3 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:101.18,103.5 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:109.18,111.5 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:112.9,116.4 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:120.51,122.3 1 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:138.123,142.38 3 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:169.2,171.53 2 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:187.2,188.52 2 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:192.2,192.34 1 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:142.38,144.17 2 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:147.3,147.50 1 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:144.17,146.4 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:147.50,148.65 1 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:148.65,150.5 1 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:150.10,155.5 1 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:156.9,156.67 1 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:156.67,157.52 1 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:157.52,159.5 1 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:159.10,162.5 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:163.9,166.4 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:171.53,173.17 2 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:177.3,181.17 2 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:184.3,184.49 1 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:173.17,175.4 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:181.17,183.4 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:188.52,190.3 1 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:199.9,201.71 1 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:222.2,222.12 1 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:201.71,204.17 3 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:207.3,209.70 2 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:216.3,216.55 1 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:204.17,206.4 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:209.70,214.4 1 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:216.55,219.4 1 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:225.70,227.29 2 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:232.2,232.12 1 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:235.2,235.14 1 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:227.29,228.22 1 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:228.22,230.4 1 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:232.12,234.3 1 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:238.142,244.34 4 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:248.2,248.56 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:268.2,268.57 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:244.34,246.3 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:248.56,251.90 3 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:257.3,257.54 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:251.90,253.4 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:253.9,255.4 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:257.54,261.51 3 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:261.51,263.5 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:263.10,265.5 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:273.59,276.45 2 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:293.2,293.21 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:276.45,277.49 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:277.49,283.4 2 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:283.9,284.19 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:284.19,286.5 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:286.10,286.41 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:286.41,288.5 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:296.96,299.52 3 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:311.2,311.41 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:320.2,320.58 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:325.2,325.33 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:342.2,342.12 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:299.52,300.55 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:300.55,302.51 2 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:306.4,307.54 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:302.51,304.5 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:311.41,312.23 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:312.23,314.4 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:314.9,317.4 2 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:320.58,321.23 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:321.23,323.4 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:325.33,327.53 2 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:339.3,339.74 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:327.53,328.24 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:328.24,330.5 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:330.10,331.44 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:331.44,333.43 2 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:333.43,335.7 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:349.41,353.52 3 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:357.2,366.68 8 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:409.2,409.21 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:353.52,355.3 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:366.68,375.63 4 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:402.3,403.17 2 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:406.3,406.37 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:375.63,376.44 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:396.4,396.43 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:376.44,380.5 3 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:380.10,385.71 5 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:385.71,388.6 2 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:388.11,388.74 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:388.74,391.6 2 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:391.11,394.6 2 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:396.43,400.5 3 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:403.17,405.4 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:417.51,423.33 4 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:427.2,427.27 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:436.2,436.50 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:450.2,450.33 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:456.2,456.29 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:423.33,425.3 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:427.27,428.57 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:428.57,429.42 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:429.42,432.5 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:436.50,438.17 2 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:441.3,442.49 2 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:445.3,446.36 2 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:438.17,440.4 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:442.49,444.4 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:450.33,451.45 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:451.45,453.4 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:459.155,463.37 4 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:467.2,467.48 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:479.2,479.21 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:463.37,466.3 2 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:467.48,469.17 2 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:472.3,477.5 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:469.17,471.4 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:482.94,485.33 2 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:493.2,493.8 1 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:485.33,487.3 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:487.8,487.40 1 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:487.40,489.3 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:489.8,492.3 2 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:496.101,500.34 4 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:505.2,509.42 4 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:513.2,513.34 1 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:518.2,518.19 1 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:500.34,504.3 3 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:509.42,511.3 1 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:513.34,514.57 1 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:514.57,516.4 1 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:527.3,530.56 2 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:602.2,602.20 1 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:530.56,534.45 4 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:538.3,542.72 4 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:546.3,546.36 1 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:563.3,569.32 6 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:575.3,575.44 1 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:581.3,581.37 1 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:534.45,536.4 1 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:542.72,544.4 1 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:546.36,549.51 2 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:557.4,557.51 1 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:560.4,560.69 1 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:549.51,552.5 2 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:552.10,555.5 2 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:557.51,559.5 1 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:569.32,571.4 1 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:571.9,573.4 1 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:575.44,579.4 2 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:581.37,584.18 3 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:588.4,594.5 1 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:584.18,586.5 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:596.9,600.4 3 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:605.107,609.46 3 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:624.2,626.41 3 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:632.2,632.46 1 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:609.46,611.17 2 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:615.3,616.42 2 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:611.17,613.4 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:616.42,619.4 2 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:619.9,621.4 1 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:626.41,631.3 3 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:635.135,636.22 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:639.2,639.82 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:636.22,638.3 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:642.97,643.22 1 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:643.22,645.3 1 1 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:645.8,647.3 1 0 +github.com/feast-dev/feast/go/internal/feast/onlineserving/serving.go:655.51,657.2 1 0 +github.com/feast-dev/feast/go/main.go:33.198,35.2 1 0 +github.com/feast-dev/feast/go/main.go:37.198,39.2 1 0 +github.com/feast-dev/feast/go/main.go:41.13,49.16 6 0 +github.com/feast-dev/feast/go/main.go:53.2,61.16 7 0 +github.com/feast-dev/feast/go/main.go:65.2,66.16 2 0 +github.com/feast-dev/feast/go/main.go:70.2,71.16 2 0 +github.com/feast-dev/feast/go/main.go:77.2,77.26 1 0 +github.com/feast-dev/feast/go/main.go:85.2,85.16 1 0 +github.com/feast-dev/feast/go/main.go:49.16,51.3 1 0 +github.com/feast-dev/feast/go/main.go:61.16,63.3 1 0 +github.com/feast-dev/feast/go/main.go:66.16,68.3 1 0 +github.com/feast-dev/feast/go/main.go:71.16,73.3 1 0 +github.com/feast-dev/feast/go/main.go:77.26,79.3 1 0 +github.com/feast-dev/feast/go/main.go:79.8,79.33 1 0 +github.com/feast-dev/feast/go/main.go:79.33,81.3 1 0 +github.com/feast-dev/feast/go/main.go:81.8,83.3 1 0 +github.com/feast-dev/feast/go/main.go:85.16,87.3 1 0 +github.com/feast-dev/feast/go/main.go:91.187,93.40 2 1 +github.com/feast-dev/feast/go/main.go:109.2,109.28 1 1 +github.com/feast-dev/feast/go/main.go:93.40,95.17 2 0 +github.com/feast-dev/feast/go/main.go:99.3,105.17 2 0 +github.com/feast-dev/feast/go/main.go:95.17,97.4 1 0 +github.com/feast-dev/feast/go/main.go:105.17,107.4 1 0 +github.com/feast-dev/feast/go/main.go:113.175,114.68 1 0 +github.com/feast-dev/feast/go/main.go:118.2,119.16 2 0 +github.com/feast-dev/feast/go/main.go:122.2,125.16 4 0 +github.com/feast-dev/feast/go/main.go:129.2,137.12 7 0 +github.com/feast-dev/feast/go/main.go:148.2,148.30 1 0 +github.com/feast-dev/feast/go/main.go:114.68,117.3 2 0 +github.com/feast-dev/feast/go/main.go:119.16,121.3 1 0 +github.com/feast-dev/feast/go/main.go:125.16,127.3 1 0 +github.com/feast-dev/feast/go/main.go:137.12,142.28 4 0 +github.com/feast-dev/feast/go/main.go:145.3,145.43 1 0 +github.com/feast-dev/feast/go/main.go:142.28,144.4 1 0 +github.com/feast-dev/feast/go/main.go:154.175,156.16 2 0 +github.com/feast-dev/feast/go/main.go:159.2,165.12 5 0 +github.com/feast-dev/feast/go/main.go:179.2,179.30 1 0 +github.com/feast-dev/feast/go/main.go:156.16,158.3 1 0 +github.com/feast-dev/feast/go/main.go:165.12,170.17 4 0 +github.com/feast-dev/feast/go/main.go:173.3,173.28 1 0 +github.com/feast-dev/feast/go/main.go:176.3,176.43 1 0 +github.com/feast-dev/feast/go/main.go:170.17,172.4 1 0 +github.com/feast-dev/feast/go/main.go:173.28,175.4 1 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/onlinestore.go:44.82,45.59 1 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/onlinestore.go:45.59,48.3 1 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/onlinestore.go:48.8,51.3 2 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/onlinestore.go:54.71,56.9 2 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/onlinestore.go:56.9,58.3 1 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/onlinestore.go:58.8,58.40 1 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/onlinestore.go:58.40,61.3 2 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/onlinestore.go:61.8,61.39 1 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/onlinestore.go:61.39,64.3 2 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/onlinestore.go:64.8,66.3 1 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:52.140,65.16 7 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:68.2,72.9 3 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:76.2,76.53 1 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:109.2,110.33 2 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:114.2,114.33 1 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:136.2,136.20 1 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:65.16,67.3 1 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:72.9,75.3 1 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:76.53,78.3 1 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:78.8,80.30 2 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:80.30,81.35 1 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:81.35,83.5 1 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:83.10,83.42 1 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:83.42,85.28 2 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:85.28,87.6 1 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:87.11,87.30 1 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:87.30,89.20 2 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:89.20,91.7 1 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:91.12,91.23 1 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:91.23,93.7 1 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:94.11,94.29 1 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:94.29,96.20 2 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:96.20,98.7 1 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:99.11,101.6 1 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:102.10,104.5 1 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:110.33,112.3 1 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:114.33,121.75 2 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:121.75,123.4 1 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:124.8,124.43 1 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:124.43,131.75 2 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:131.75,133.4 1 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:139.80,143.9 3 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:157.2,157.15 1 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:143.9,146.3 1 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:146.8,146.60 1 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:146.60,148.3 1 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:148.8,149.30 1 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:149.30,151.4 1 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:151.9,151.45 1 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:151.45,153.4 1 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:153.9,155.4 1 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:160.140,164.51 4 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:171.2,171.54 1 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:164.51,165.56 1 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:165.56,169.4 3 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:174.159,181.36 6 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:188.2,188.40 1 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:194.2,194.31 1 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:181.36,187.3 5 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:188.40,193.3 4 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:197.109,200.39 3 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:208.2,208.46 1 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:200.39,202.17 2 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:205.3,206.42 2 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:202.17,204.4 1 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:211.166,219.16 7 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:223.2,226.22 3 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:247.2,249.41 3 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:323.2,323.21 1 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:219.16,221.3 1 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:226.22,228.38 2 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:232.3,233.17 2 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:228.38,231.4 2 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:233.17,235.4 1 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:236.8,236.32 1 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:236.32,238.38 2 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:242.3,243.17 2 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:238.38,241.4 2 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:243.17,245.4 1 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:249.41,256.17 5 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:260.3,262.44 2 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:317.3,317.25 1 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:256.17,258.4 1 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:262.44,263.36 1 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:267.4,267.24 1 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:263.36,264.10 1 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:267.24,273.34 5 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:283.5,286.6 1 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:273.34,274.65 1 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:274.65,276.7 1 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:276.12,277.82 1 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:277.82,279.8 1 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:288.10,288.57 1 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:288.57,290.5 1 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:290.10,293.72 3 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:293.72,295.6 1 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:295.11,300.35 5 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:309.6,312.7 1 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:300.35,301.66 1 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:301.66,303.8 1 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:303.13,304.83 1 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:304.83,306.9 1 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:317.25,319.4 1 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:327.40,329.2 0 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:331.118,333.16 2 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:336.2,337.22 2 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:333.16,335.3 1 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:340.107,344.60 1 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:349.2,351.47 2 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:355.2,356.36 2 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:359.2,365.33 4 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:373.2,373.33 1 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:394.2,395.39 2 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:399.2,399.30 1 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:344.60,346.3 1 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:351.47,353.3 1 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:356.36,358.3 1 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:365.33,371.3 5 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:373.33,378.17 4 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:382.3,390.37 7 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:378.17,380.4 1 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:395.39,397.3 1 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:402.116,404.29 1 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:405.30,407.51 2 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:408.29,409.49 1 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:410.29,413.50 3 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:414.29,415.41 1 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:425.11,426.85 1 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:427.10,428.85 1 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:415.41,420.4 3 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/redisonlinestore.go:420.9,424.4 3 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/sqliteonlinestore.go:35.146,37.51 2 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/sqliteonlinestore.go:53.2,53.20 1 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/sqliteonlinestore.go:37.51,39.3 1 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/sqliteonlinestore.go:39.8,40.45 1 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/sqliteonlinestore.go:40.45,42.4 1 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/sqliteonlinestore.go:42.9,46.18 3 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/sqliteonlinestore.go:49.4,49.17 1 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/sqliteonlinestore.go:46.18,48.5 1 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/sqliteonlinestore.go:56.40,58.2 1 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/sqliteonlinestore.go:62.167,65.16 3 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/sqliteonlinestore.go:68.2,73.39 6 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/sqliteonlinestore.go:84.2,85.38 2 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/sqliteonlinestore.go:89.2,89.51 1 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/sqliteonlinestore.go:122.2,122.21 1 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/sqliteonlinestore.go:65.16,67.3 1 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/sqliteonlinestore.go:73.39,75.17 2 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/sqliteonlinestore.go:79.3,82.35 3 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/sqliteonlinestore.go:75.17,77.4 1 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/sqliteonlinestore.go:85.38,87.3 1 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/sqliteonlinestore.go:89.51,95.17 3 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/sqliteonlinestore.go:98.3,99.19 2 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/sqliteonlinestore.go:95.17,97.4 1 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/sqliteonlinestore.go:99.19,106.18 7 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/sqliteonlinestore.go:109.4,109.63 1 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/sqliteonlinestore.go:112.4,113.30 2 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/sqliteonlinestore.go:116.4,119.5 1 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/sqliteonlinestore.go:106.18,108.5 1 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/sqliteonlinestore.go:109.63,111.5 1 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/sqliteonlinestore.go:113.30,115.5 1 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/sqliteonlinestore.go:126.62,129.17 3 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/sqliteonlinestore.go:139.2,139.18 1 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/sqliteonlinestore.go:129.17,130.19 1 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/sqliteonlinestore.go:133.3,135.17 3 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/sqliteonlinestore.go:130.19,132.4 1 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/sqliteonlinestore.go:135.17,137.4 1 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/sqliteonlinestore.go:143.61,145.2 1 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/sqliteonlinestore.go:148.60,150.16 2 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/sqliteonlinestore.go:153.2,153.16 1 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/sqliteonlinestore.go:150.16,152.3 1 0 +github.com/feast-dev/feast/go/internal/feast/onlinestore/sqliteonlinestore.go:156.66,157.32 1 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/sqliteonlinestore.go:160.2,163.18 4 1 +github.com/feast-dev/feast/go/internal/feast/onlinestore/sqliteonlinestore.go:157.32,159.3 1 0 diff --git a/go/internal/feast/featurestore.go b/go/internal/feast/featurestore.go index 390b011851..4b0f1494d1 100644 --- a/go/internal/feast/featurestore.go +++ b/go/internal/feast/featurestore.go @@ -19,6 +19,15 @@ import ( prototypes "github.com/feast-dev/feast/go/protos/feast/types" ) +type FeatureStoreInterface interface { + GetOnlineFeatures( + ctx context.Context, + featureRefs []string, + featureService *model.FeatureService, + joinKeyToEntityValues map[string]*prototypes.RepeatedValue, + requestData map[string]*prototypes.RepeatedValue, + fullFeatureNames bool) ([]*onlineserving.FeatureVector, error) +} type FeatureStore struct { config *registry.RepoConfig registry *registry.Registry @@ -85,7 +94,7 @@ func (fs *FeatureStore) GetOnlineFeatures( joinKeyToEntityValues map[string]*prototypes.RepeatedValue, requestData map[string]*prototypes.RepeatedValue, fullFeatureNames bool) ([]*onlineserving.FeatureVector, error) { - fvs, odFvs, err := fs.listAllViews() + fvs, odFvs, err := fs.ListAllViews() if err != nil { return nil, err } @@ -230,7 +239,7 @@ func (fs *FeatureStore) GetFeatureService(name string) (*model.FeatureService, e return fs.registry.GetFeatureService(fs.config.Project, name) } -func (fs *FeatureStore) listAllViews() (map[string]*model.FeatureView, map[string]*model.OnDemandFeatureView, error) { +func (fs *FeatureStore) ListAllViews() (map[string]*model.FeatureView, map[string]*model.OnDemandFeatureView, error) { fvs := make(map[string]*model.FeatureView) odFvs := make(map[string]*model.OnDemandFeatureView) @@ -291,6 +300,33 @@ func (fs *FeatureStore) ListEntities(hideDummyEntity bool) ([]*model.Entity, err return entities, nil } +func (fs *FeatureStore) GetEntityByKey(entityKey string) (*model.Entity, error) { + + entities, err := fs.ListEntities(false) + if err != nil { + return nil, err + } + for _, entity := range entities { + if entity.JoinKey == entityKey { + return entity, nil + } + } + return nil, fmt.Errorf("Entity with key %s not found", entityKey) +} +func (fs *FeatureStore) GetRequestSources(odfvList []*model.OnDemandFeatureView) (map[string]prototypes.ValueType_Enum, error) { + + requestSources := make(map[string]prototypes.ValueType_Enum, 0) + if len(odfvList) > 0 { + for _, odfv := range odfvList { + schema := odfv.GetRequestDataSchema() + for name, dtype := range schema { + requestSources[name] = dtype + } + } + } + return requestSources, nil +} + func (fs *FeatureStore) ListOnDemandFeatureViews() ([]*model.OnDemandFeatureView, error) { return fs.registry.ListOnDemandFeatureViews(fs.config.Project) } @@ -311,6 +347,14 @@ func (fs *FeatureStore) GetFeatureView(featureViewName string, hideDummyEntity b return fv, nil } +func (fs *FeatureStore) GetOnDemandFeatureView(featureViewName string) (*model.OnDemandFeatureView, error) { + fv, err := fs.registry.GetOnDemandFeatureView(fs.config.Project, featureViewName) + if err != nil { + return nil, err + } + return fv, nil +} + func (fs *FeatureStore) readFromOnlineStore(ctx context.Context, entityRows []*prototypes.EntityKey, requestedFeatureViewNames []string, requestedFeatureNames []string, diff --git a/go/internal/feast/featurestore_test.go b/go/internal/feast/featurestore_test.go index dd08bc287e..3f755eb999 100644 --- a/go/internal/feast/featurestore_test.go +++ b/go/internal/feast/featurestore_test.go @@ -2,30 +2,17 @@ package feast import ( "context" - "path/filepath" - "runtime" + "github.com/feast-dev/feast/go/internal/feast/model" + "github.com/feast-dev/feast/go/protos/feast/core" "testing" "github.com/stretchr/testify/assert" "github.com/feast-dev/feast/go/internal/feast/onlinestore" "github.com/feast-dev/feast/go/internal/feast/registry" - "github.com/feast-dev/feast/go/protos/feast/types" + types "github.com/feast-dev/feast/go/protos/feast/types" ) -// Return absolute path to the test_repo registry regardless of the working directory -func getRegistryPath() map[string]interface{} { - // Get the file path of this source file, regardless of the working directory - _, filename, _, ok := runtime.Caller(0) - if !ok { - panic("couldn't find file path of the test file") - } - registry := map[string]interface{}{ - "path": filepath.Join(filename, "..", "..", "..", "feature_repo/data/registry.db"), - } - return registry -} - func TestNewFeatureStore(t *testing.T) { t.Skip("@todo(achals): feature_repo isn't checked in yet") config := registry.RepoConfig{ @@ -70,3 +57,68 @@ func TestGetOnlineFeaturesRedis(t *testing.T) { assert.Nil(t, err) assert.Len(t, response, 4) // 3 Features + 1 entity = 4 columns (feature vectors) in response } +func TestGetRequestSources(t *testing.T) { + config := GetRepoConfig() + fs, _ := NewFeatureStore(&config, nil) + + odfv := &core.OnDemandFeatureView{ + Spec: &core.OnDemandFeatureViewSpec{ + Name: "odfv1", + Project: "feature_repo", + Sources: map[string]*core.OnDemandSource{ + "odfv1": { + Source: &core.OnDemandSource_RequestDataSource{ + RequestDataSource: &core.DataSource{ + Name: "request_source_1", + Type: core.DataSource_REQUEST_SOURCE, + Options: &core.DataSource_RequestDataOptions_{ + RequestDataOptions: &core.DataSource_RequestDataOptions{ + DeprecatedSchema: map[string]types.ValueType_Enum{ + "feature1": types.ValueType_INT64, + }, + Schema: []*core.FeatureSpecV2{ + { + Name: "feat1", + ValueType: types.ValueType_INT64, + }, + }, + }, + }, + }, + }, + }, + }, + }, + } + + cached_odfv := &model.OnDemandFeatureView{ + Base: model.NewBaseFeatureView("odfv1", []*core.FeatureSpecV2{ + { + Name: "feat1", + ValueType: types.ValueType_INT64, + }, + }), + SourceFeatureViewProjections: make(map[string]*model.FeatureViewProjection), + SourceRequestDataSources: map[string]*core.DataSource_RequestDataOptions{ + "request_source_1": { + Schema: []*core.FeatureSpecV2{ + { + Name: "feat1", + ValueType: types.ValueType_INT64, + }, + }, + }, + }, + } + fVList := make([]*model.OnDemandFeatureView, 0) + fVList = append(fVList, cached_odfv) + cachedOnDemandFVs := make(map[string]map[string]*core.OnDemandFeatureView) + cachedOnDemandFVs["feature_repo"] = make(map[string]*core.OnDemandFeatureView) + cachedOnDemandFVs["feature_repo"]["odfv1"] = odfv + fs.registry.CachedOnDemandFeatureViews = cachedOnDemandFVs + requestSources, err := fs.GetRequestSources(fVList) + + assert.Nil(t, err) + assert.Equal(t, 1, len(requestSources)) + assert.Equal(t, types.ValueType_INT64.Enum(), requestSources["feat1"].Enum()) +} diff --git a/go/internal/feast/model/entity.go b/go/internal/feast/model/entity.go index 5a09edb655..736920346d 100644 --- a/go/internal/feast/model/entity.go +++ b/go/internal/feast/model/entity.go @@ -2,16 +2,19 @@ package model import ( "github.com/feast-dev/feast/go/protos/feast/core" + "github.com/feast-dev/feast/go/protos/feast/types" ) type Entity struct { - Name string - JoinKey string + Name string + JoinKey string + ValueType types.ValueType_Enum } func NewEntityFromProto(proto *core.Entity) *Entity { return &Entity{ - Name: proto.Spec.Name, - JoinKey: proto.Spec.JoinKey, + Name: proto.Spec.Name, + JoinKey: proto.Spec.JoinKey, + ValueType: proto.Spec.ValueType, } } diff --git a/go/internal/feast/registry/registry.go b/go/internal/feast/registry/registry.go index 6ff6f20641..60c55c8380 100644 --- a/go/internal/feast/registry/registry.go +++ b/go/internal/feast/registry/registry.go @@ -31,11 +31,11 @@ var REGISTRY_STORE_CLASS_FOR_SCHEME map[string]string = map[string]string{ type Registry struct { project string registryStore RegistryStore - cachedFeatureServices map[string]map[string]*core.FeatureService - cachedEntities map[string]map[string]*core.Entity - cachedFeatureViews map[string]map[string]*core.FeatureView + CachedFeatureServices map[string]map[string]*core.FeatureService + CachedEntities map[string]map[string]*core.Entity + CachedFeatureViews map[string]map[string]*core.FeatureView cachedStreamFeatureViews map[string]map[string]*core.StreamFeatureView - cachedOnDemandFeatureViews map[string]map[string]*core.OnDemandFeatureView + CachedOnDemandFeatureViews map[string]map[string]*core.OnDemandFeatureView cachedRegistry *core.Registry cachedRegistryProtoLastUpdated time.Time cachedRegistryProtoTtl time.Duration @@ -113,11 +113,11 @@ func (r *Registry) load(registry *core.Registry) { r.mu.Lock() defer r.mu.Unlock() r.cachedRegistry = registry - r.cachedFeatureServices = make(map[string]map[string]*core.FeatureService) - r.cachedEntities = make(map[string]map[string]*core.Entity) - r.cachedFeatureViews = make(map[string]map[string]*core.FeatureView) + r.CachedFeatureServices = make(map[string]map[string]*core.FeatureService) + r.CachedEntities = make(map[string]map[string]*core.Entity) + r.CachedFeatureViews = make(map[string]map[string]*core.FeatureView) r.cachedStreamFeatureViews = make(map[string]map[string]*core.StreamFeatureView) - r.cachedOnDemandFeatureViews = make(map[string]map[string]*core.OnDemandFeatureView) + r.CachedOnDemandFeatureViews = make(map[string]map[string]*core.OnDemandFeatureView) r.loadEntities(registry) r.loadFeatureServices(registry) r.loadFeatureViews(registry) @@ -129,30 +129,30 @@ func (r *Registry) load(registry *core.Registry) { func (r *Registry) loadEntities(registry *core.Registry) { entities := registry.Entities for _, entity := range entities { - if _, ok := r.cachedEntities[r.project]; !ok { - r.cachedEntities[r.project] = make(map[string]*core.Entity) + if _, ok := r.CachedEntities[r.project]; !ok { + r.CachedEntities[r.project] = make(map[string]*core.Entity) } - r.cachedEntities[r.project][entity.Spec.Name] = entity + r.CachedEntities[r.project][entity.Spec.Name] = entity } } func (r *Registry) loadFeatureServices(registry *core.Registry) { featureServices := registry.FeatureServices for _, featureService := range featureServices { - if _, ok := r.cachedFeatureServices[r.project]; !ok { - r.cachedFeatureServices[r.project] = make(map[string]*core.FeatureService) + if _, ok := r.CachedFeatureServices[r.project]; !ok { + r.CachedFeatureServices[r.project] = make(map[string]*core.FeatureService) } - r.cachedFeatureServices[r.project][featureService.Spec.Name] = featureService + r.CachedFeatureServices[r.project][featureService.Spec.Name] = featureService } } func (r *Registry) loadFeatureViews(registry *core.Registry) { featureViews := registry.FeatureViews for _, featureView := range featureViews { - if _, ok := r.cachedFeatureViews[r.project]; !ok { - r.cachedFeatureViews[r.project] = make(map[string]*core.FeatureView) + if _, ok := r.CachedFeatureViews[r.project]; !ok { + r.CachedFeatureViews[r.project] = make(map[string]*core.FeatureView) } - r.cachedFeatureViews[r.project][featureView.Spec.Name] = featureView + r.CachedFeatureViews[r.project][featureView.Spec.Name] = featureView } } @@ -169,10 +169,10 @@ func (r *Registry) loadStreamFeatureViews(registry *core.Registry) { func (r *Registry) loadOnDemandFeatureViews(registry *core.Registry) { onDemandFeatureViews := registry.OnDemandFeatureViews for _, onDemandFeatureView := range onDemandFeatureViews { - if _, ok := r.cachedOnDemandFeatureViews[r.project]; !ok { - r.cachedOnDemandFeatureViews[r.project] = make(map[string]*core.OnDemandFeatureView) + if _, ok := r.CachedOnDemandFeatureViews[r.project]; !ok { + r.CachedOnDemandFeatureViews[r.project] = make(map[string]*core.OnDemandFeatureView) } - r.cachedOnDemandFeatureViews[r.project][onDemandFeatureView.Spec.Name] = onDemandFeatureView + r.CachedOnDemandFeatureViews[r.project][onDemandFeatureView.Spec.Name] = onDemandFeatureView } } @@ -184,7 +184,7 @@ func (r *Registry) loadOnDemandFeatureViews(registry *core.Registry) { func (r *Registry) ListEntities(project string) ([]*model.Entity, error) { r.mu.RLock() defer r.mu.RUnlock() - if cachedEntities, ok := r.cachedEntities[project]; !ok { + if cachedEntities, ok := r.CachedEntities[project]; !ok { return []*model.Entity{}, nil } else { entities := make([]*model.Entity, len(cachedEntities)) @@ -205,7 +205,7 @@ func (r *Registry) ListEntities(project string) ([]*model.Entity, error) { func (r *Registry) ListFeatureViews(project string) ([]*model.FeatureView, error) { r.mu.RLock() defer r.mu.RUnlock() - if cachedFeatureViews, ok := r.cachedFeatureViews[project]; !ok { + if cachedFeatureViews, ok := r.CachedFeatureViews[project]; !ok { return []*model.FeatureView{}, nil } else { featureViews := make([]*model.FeatureView, len(cachedFeatureViews)) @@ -247,7 +247,7 @@ func (r *Registry) ListStreamFeatureViews(project string) ([]*model.FeatureView, func (r *Registry) ListFeatureServices(project string) ([]*model.FeatureService, error) { r.mu.RLock() defer r.mu.RUnlock() - if cachedFeatureServices, ok := r.cachedFeatureServices[project]; !ok { + if cachedFeatureServices, ok := r.CachedFeatureServices[project]; !ok { return []*model.FeatureService{}, nil } else { featureServices := make([]*model.FeatureService, len(cachedFeatureServices)) @@ -268,7 +268,7 @@ func (r *Registry) ListFeatureServices(project string) ([]*model.FeatureService, func (r *Registry) ListOnDemandFeatureViews(project string) ([]*model.OnDemandFeatureView, error) { r.mu.RLock() defer r.mu.RUnlock() - if cachedOnDemandFeatureViews, ok := r.cachedOnDemandFeatureViews[project]; !ok { + if cachedOnDemandFeatureViews, ok := r.CachedOnDemandFeatureViews[project]; !ok { return []*model.OnDemandFeatureView{}, nil } else { onDemandFeatureViews := make([]*model.OnDemandFeatureView, len(cachedOnDemandFeatureViews)) @@ -284,7 +284,7 @@ func (r *Registry) ListOnDemandFeatureViews(project string) ([]*model.OnDemandFe func (r *Registry) GetEntity(project, entityName string) (*model.Entity, error) { r.mu.RLock() defer r.mu.RUnlock() - if cachedEntities, ok := r.cachedEntities[project]; !ok { + if cachedEntities, ok := r.CachedEntities[project]; !ok { return nil, fmt.Errorf("no cached entities found for project %s", project) } else { if entity, ok := cachedEntities[entityName]; !ok { @@ -298,7 +298,7 @@ func (r *Registry) GetEntity(project, entityName string) (*model.Entity, error) func (r *Registry) GetFeatureView(project, featureViewName string) (*model.FeatureView, error) { r.mu.RLock() defer r.mu.RUnlock() - if cachedFeatureViews, ok := r.cachedFeatureViews[project]; !ok { + if cachedFeatureViews, ok := r.CachedFeatureViews[project]; !ok { return nil, fmt.Errorf("no cached feature views found for project %s", project) } else { if featureViewProto, ok := cachedFeatureViews[featureViewName]; !ok { @@ -326,7 +326,7 @@ func (r *Registry) GetStreamFeatureView(project, streamFeatureViewName string) ( func (r *Registry) GetFeatureService(project, featureServiceName string) (*model.FeatureService, error) { r.mu.RLock() defer r.mu.RUnlock() - if cachedFeatureServices, ok := r.cachedFeatureServices[project]; !ok { + if cachedFeatureServices, ok := r.CachedFeatureServices[project]; !ok { return nil, fmt.Errorf("no cached feature services found for project %s", project) } else { if featureServiceProto, ok := cachedFeatureServices[featureServiceName]; !ok { @@ -340,7 +340,7 @@ func (r *Registry) GetFeatureService(project, featureServiceName string) (*model func (r *Registry) GetOnDemandFeatureView(project, onDemandFeatureViewName string) (*model.OnDemandFeatureView, error) { r.mu.RLock() defer r.mu.RUnlock() - if cachedOnDemandFeatureViews, ok := r.cachedOnDemandFeatureViews[project]; !ok { + if cachedOnDemandFeatureViews, ok := r.CachedOnDemandFeatureViews[project]; !ok { return nil, fmt.Errorf("no cached on demand feature views found for project %s", project) } else { if onDemandFeatureViewProto, ok := cachedOnDemandFeatureViews[onDemandFeatureViewName]; !ok { diff --git a/go/internal/feast/server/http_server.go b/go/internal/feast/server/http_server.go index 2e5f766c7d..bb7774942f 100644 --- a/go/internal/feast/server/http_server.go +++ b/go/internal/feast/server/http_server.go @@ -3,6 +3,7 @@ package server import ( "context" "encoding/json" + "errors" "fmt" "net/http" "os" @@ -32,10 +33,12 @@ type httpServer struct { // Some Feast types aren't supported during JSON conversion type repeatedValue struct { stringVal []string + int32Val []int32 int64Val []int64 doubleVal []float64 boolVal []bool stringListVal [][]string + int32ListVal [][]int32 int64ListVal [][]int64 doubleListVal [][]float64 boolListVal [][]bool @@ -101,6 +104,11 @@ func (u *repeatedValue) ToProto() *prototypes.RepeatedValue { proto.Val = append(proto.Val, &prototypes.Value{Val: &prototypes.Value_Int64Val{Int64Val: val}}) } } + if u.int32Val != nil { + for _, val := range u.int32Val { + proto.Val = append(proto.Val, &prototypes.Value{Val: &prototypes.Value_Int32Val{Int32Val: val}}) + } + } if u.doubleVal != nil { for _, val := range u.doubleVal { proto.Val = append(proto.Val, &prototypes.Value{Val: &prototypes.Value_DoubleVal{DoubleVal: val}}) @@ -116,6 +124,11 @@ func (u *repeatedValue) ToProto() *prototypes.RepeatedValue { proto.Val = append(proto.Val, &prototypes.Value{Val: &prototypes.Value_StringListVal{StringListVal: &prototypes.StringList{Val: val}}}) } } + if u.int32ListVal != nil { + for _, val := range u.int32ListVal { + proto.Val = append(proto.Val, &prototypes.Value{Val: &prototypes.Value_Int32ListVal{Int32ListVal: &prototypes.Int32List{Val: val}}}) + } + } if u.int64ListVal != nil { for _, val := range u.int64ListVal { proto.Val = append(proto.Val, &prototypes.Value{Val: &prototypes.Value_Int64ListVal{Int64ListVal: &prototypes.Int64List{Val: val}}}) @@ -146,6 +159,21 @@ func NewHttpServer(fs *feast.FeatureStore, loggingService *logging.LoggingServic return &httpServer{fs: fs, loggingService: loggingService} } +/* +* +Used to align a field specified in the request with its defined schema type. +*/ +func typecastToFieldSchemaType(val *repeatedValue, fieldType prototypes.ValueType_Enum) { + if val.int64Val != nil { + if fieldType == prototypes.ValueType_INT32 { + for _, v := range val.int64Val { + val.int32Val = append(val.int32Val, int32(v)) + } + val.int64Val = nil + } + } +} + func (s *httpServer) getOnlineFeatures(w http.ResponseWriter, r *http.Request) { var err error @@ -180,21 +208,85 @@ func (s *httpServer) getOnlineFeatures(w http.ResponseWriter, r *http.Request) { return } var featureService *model.FeatureService - if request.FeatureService != nil { + var entitiesProto = make(map[string]*prototypes.RepeatedValue) + var requestContextProto = make(map[string]*prototypes.RepeatedValue) + var odfVList = make([]*model.OnDemandFeatureView, 0) + var requestSources = make(map[string]prototypes.ValueType_Enum) + + if request.FeatureService != nil && *request.FeatureService != "" { featureService, err = s.fs.GetFeatureService(*request.FeatureService) if err != nil { logSpanContext.Error().Err(err).Msg("Error getting feature service from registry") writeJSONError(w, fmt.Errorf("Error getting feature service from registry: %+v", err), http.StatusInternalServerError) return } + for _, fv := range featureService.Projections { + odfv, _ := s.fs.GetOnDemandFeatureView(fv.Name) + if odfv != nil { + odfVList = append(odfVList, odfv) + } + } + } else if len(request.Features) > 0 { + log.Info().Msgf("request.Features %v", request.Features) + for _, featureName := range request.Features { + fVName, _, err := onlineserving.ParseFeatureReference(featureName) + if err != nil { + logSpanContext.Error().Err(err) + writeJSONError(w, fmt.Errorf("Error parsing feature reference %s", featureName), http.StatusBadRequest) + return + } + fv, odfv, _ := s.fs.ListAllViews() + if _, ok1 := odfv[fVName]; ok1 { + odfVList = append(odfVList, odfv[fVName]) + } else if _, ok1 := fv[fVName]; !ok1 { + logSpanContext.Error().Msg("Feature View not found") + writeJSONError(w, fmt.Errorf("Feature View %s not found", featureName), http.StatusInternalServerError) + return + } + } + } else { + logSpanContext.Error().Msg("No Feature Views or Feature Services specified in the request") + writeJSONError(w, errors.New("No Feature Views or Feature Services specified in the request"), http.StatusBadRequest) + return } - entitiesProto := make(map[string]*prototypes.RepeatedValue) - for key, value := range request.Entities { - entitiesProto[key] = value.ToProto() + if odfVList != nil { + requestSources, _ = s.fs.GetRequestSources(odfVList) } - requestContextProto := make(map[string]*prototypes.RepeatedValue) - for key, value := range request.RequestContext { - requestContextProto[key] = value.ToProto() + if len(request.Entities) > 0 { + var entityType prototypes.ValueType_Enum + for key, value := range request.Entities { + entity, err := s.fs.GetEntityByKey(key) + if err != nil { + if len(requestSources) == 0 { + logSpanContext.Error().Err(err) + writeJSONError(w, err, http.StatusNotFound) + return + } + requestSourceType, ok := requestSources[key] + if !ok { + logSpanContext.Error().Msgf("Entity with key or Request Source with name %s not found ", key) + writeJSONError(w, fmt.Errorf("Entity with key or Request Source with name %s not found ", key), http.StatusNotFound) + return + } + entityType = requestSourceType + } else { + entityType = entity.ValueType + } + typecastToFieldSchemaType(&value, entityType) + entitiesProto[key] = value.ToProto() + } + } + if request.RequestContext != nil && len(request.RequestContext) > 0 { + for key, value := range request.RequestContext { + requestSourceType, ok := requestSources[key] + if !ok { + logSpanContext.Error().Msgf("Request Source %s not found ", key) + writeJSONError(w, fmt.Errorf("Request Source %s not found ", key), http.StatusNotFound) + return + } + typecastToFieldSchemaType(&value, requestSourceType) + requestContextProto[key] = value.ToProto() + } } featureVectors, err := s.fs.GetOnlineFeatures( diff --git a/go/internal/feast/server/http_server_test.go b/go/internal/feast/server/http_server_test.go index e0d474a9f3..721fcdc693 100644 --- a/go/internal/feast/server/http_server_test.go +++ b/go/internal/feast/server/http_server_test.go @@ -1,13 +1,17 @@ package server import ( - "encoding/json" - "testing" - - "github.com/apache/arrow/go/v17/arrow" - "github.com/apache/arrow/go/v17/arrow/array" - "github.com/apache/arrow/go/v17/arrow/memory" + "github.com/feast-dev/feast/go/internal/feast" + "github.com/feast-dev/feast/go/protos/feast/core" + "github.com/feast-dev/feast/go/protos/feast/types" "github.com/stretchr/testify/assert" + "google.golang.org/protobuf/types/known/durationpb" + "google.golang.org/protobuf/types/known/timestamppb" + "io" + "net/http" + "net/http/httptest" + "strings" + "testing" ) func TestUnmarshalJSON(t *testing.T) { @@ -43,36 +47,1120 @@ func TestUnmarshalJSON(t *testing.T) { assert.Nil(t, u.UnmarshalJSON([]byte("[[true, false, true], [false, true, false]]"))) assert.Equal(t, [][]bool{{true, false, true}, {false, true, false}}, u.boolListVal) } -func TestMarshalInt32JSON(t *testing.T) { - var arrowArray arrow.Array - memoryPool := memory.NewGoAllocator() - builder := array.NewInt32Builder(memoryPool) - defer builder.Release() - builder.AppendValues([]int32{1, 2, 3, 4}, nil) - arrowArray = builder.NewArray() - defer arrowArray.Release() - expectedJSON := `[1,2,3,4]` - - jsonData, err := json.Marshal(arrowArray) - assert.NoError(t, err, "Error marshaling Arrow array") - - assert.Equal(t, expectedJSON, string(jsonData), "JSON output does not match expected") - assert.IsType(t, &array.Int32{}, arrowArray, "arrowArray is not of type *array.Int32") + +func TestGetOnlineFeaturesWithValidRequest(t *testing.T) { + s := NewHttpServer(nil, nil) + + config := feast.GetRepoConfig() + s.fs, _ = feast.NewFeatureStore(&config, nil) + jsonRequest := `{ + "features": ["fv1:feat1", "fv1:feat2"], + "entities": { + "join_key_1": [1, 2], + "join_key_2": ["value1", "value2"] + } + }` + + fv := &core.FeatureView{ + Spec: &core.FeatureViewSpec{ + Name: "fv1", + Features: []*core.FeatureSpecV2{ + { + Name: "feat1", + ValueType: types.ValueType_INT64, + }, + { + Name: "feat2", + ValueType: types.ValueType_STRING, + }, + }, + Ttl: &durationpb.Duration{ + Seconds: 3600, // 1 hour + Nanos: 0, + }, + Entities: []string{"entity1", "entity2"}, + }, + } + + entity1 := &core.Entity{ + Spec: &core.EntitySpecV2{ + Name: "entity1", + Project: "feature_repo", + ValueType: types.ValueType_INT32, + Description: "This is a sample entity", + JoinKey: "join_key_1", + Tags: map[string]string{ + "tag1": "value1", + "tag2": "value2", + }, + Owner: "sample_owner", + }, + Meta: &core.EntityMeta{ + CreatedTimestamp: timestamppb.Now(), + LastUpdatedTimestamp: timestamppb.Now(), + }, + } + + entity2 := &core.Entity{ + Spec: &core.EntitySpecV2{ + Name: "entity2", + Project: "feature_repo", + ValueType: types.ValueType_STRING, + Description: "This is a sample entity", + JoinKey: "join_key_2", + Tags: map[string]string{ + "tag1": "value1", + "tag2": "value2", + }, + Owner: "sample_owner", + }, + Meta: &core.EntityMeta{ + CreatedTimestamp: timestamppb.Now(), + LastUpdatedTimestamp: timestamppb.Now(), + }, + } + + cachedFVs := make(map[string]map[string]*core.FeatureView) + cachedFVs["feature_repo"] = make(map[string]*core.FeatureView) + cachedFVs["feature_repo"]["fv1"] = fv + + cachedEntities := make(map[string]map[string]*core.Entity) + cachedEntities["feature_repo"] = make(map[string]*core.Entity) + cachedEntities["feature_repo"]["entity1"] = entity1 + cachedEntities["feature_repo"]["entity2"] = entity2 + + s.fs.Registry().CachedFeatureViews = cachedFVs + s.fs.Registry().CachedEntities = cachedEntities + + req, _ := http.NewRequest("POST", "/get-online-features", strings.NewReader(jsonRequest)) + rr := httptest.NewRecorder() + + req.Header.Set("Content-Type", "application/json") + s.getOnlineFeatures(rr, req) + + // Retrieve connection error string (as currently there's no mock for OnlineStore) + bodyBytes, _ := io.ReadAll(rr.Body) + bodyString := string(bodyBytes) + + // Error is only due to connection error resulting from not mocking + assert.Equal(t, http.StatusInternalServerError, rr.Code) + strings.Contains(bodyString, "connection refused") +} +func TestGetOnlineFeaturesWithEmptyFeatures(t *testing.T) { + s := NewHttpServer(nil, nil) + + config := feast.GetRepoConfig() + s.fs, _ = feast.NewFeatureStore(&config, nil) + + jsonRequest := `{ + "entities": { + "entity1": [1, 2, 3], + "entity2": ["value1", "value2"] + } + }` + + fv := &core.FeatureView{ + Spec: &core.FeatureViewSpec{ + Name: "fv1", + Features: []*core.FeatureSpecV2{ + { + Name: "feat1", + ValueType: types.ValueType_INT64, + }, + { + Name: "feat2", + ValueType: types.ValueType_STRING, + }, + }, + Ttl: &durationpb.Duration{ + Seconds: 3600, // 1 hour + Nanos: 0, + }, + Entities: []string{"entity1", "entity2"}, + }, + } + + entity1 := &core.Entity{ + Spec: &core.EntitySpecV2{ + Name: "entity1", + Project: "feature_repo", + ValueType: types.ValueType_INT32, + Description: "This is a sample entity", + JoinKey: "join_key_1", + Tags: map[string]string{ + "tag1": "value1", + "tag2": "value2", + }, + Owner: "sample_owner", + }, + Meta: &core.EntityMeta{ + CreatedTimestamp: timestamppb.Now(), + LastUpdatedTimestamp: timestamppb.Now(), + }, + } + + entity2 := &core.Entity{ + Spec: &core.EntitySpecV2{ + Name: "entity2", + Project: "feature_repo", + ValueType: types.ValueType_STRING, + Description: "This is a sample entity", + JoinKey: "join_key_2", + Tags: map[string]string{ + "tag1": "value1", + "tag2": "value2", + }, + Owner: "sample_owner", + }, + Meta: &core.EntityMeta{ + CreatedTimestamp: timestamppb.Now(), + LastUpdatedTimestamp: timestamppb.Now(), + }, + } + + cachedFVs := make(map[string]map[string]*core.FeatureView) + cachedFVs["feature_repo"] = make(map[string]*core.FeatureView) + cachedFVs["feature_repo"]["fv1"] = fv + + cachedEntities := make(map[string]map[string]*core.Entity) + cachedEntities["feature_repo"] = make(map[string]*core.Entity) + cachedEntities["feature_repo"]["entity1"] = entity1 + cachedEntities["feature_repo"]["entity2"] = entity2 + + s.fs.Registry().CachedFeatureViews = cachedFVs + s.fs.Registry().CachedEntities = cachedEntities + + req, _ := http.NewRequest("POST", "/get-online-features", strings.NewReader(jsonRequest)) + rr := httptest.NewRecorder() + + s.getOnlineFeatures(rr, req) + + assert.Equal(t, http.StatusBadRequest, rr.Code) +} + +func TestGetOnlineFeaturesWithEmptyEntities(t *testing.T) { + s := NewHttpServer(nil, nil) + + config := feast.GetRepoConfig() + s.fs, _ = feast.NewFeatureStore(&config, nil) + + jsonRequest := `{ + "features": ["fv1:feat1", "fv1:feat2"] + }` + + fv := &core.FeatureView{ + Spec: &core.FeatureViewSpec{ + Name: "fv1", + Features: []*core.FeatureSpecV2{ + { + Name: "feat1", + ValueType: types.ValueType_INT64, + }, + { + Name: "feat2", + ValueType: types.ValueType_STRING, + }, + }, + Ttl: &durationpb.Duration{ + Seconds: 3600, // 1 hour + Nanos: 0, + }, + Entities: []string{"entity1", "entity2"}, + }, + } + + entity1 := &core.Entity{ + Spec: &core.EntitySpecV2{ + Name: "entity1", + Project: "feature_repo", + ValueType: types.ValueType_INT32, + Description: "This is a sample entity", + JoinKey: "join_key_1", + Tags: map[string]string{ + "tag1": "value1", + "tag2": "value2", + }, + Owner: "sample_owner", + }, + Meta: &core.EntityMeta{ + CreatedTimestamp: timestamppb.Now(), + LastUpdatedTimestamp: timestamppb.Now(), + }, + } + + entity2 := &core.Entity{ + Spec: &core.EntitySpecV2{ + Name: "entity2", + Project: "feature_repo", + ValueType: types.ValueType_STRING, + Description: "This is a sample entity", + JoinKey: "join_key_2", + Tags: map[string]string{ + "tag1": "value1", + "tag2": "value2", + }, + Owner: "sample_owner", + }, + Meta: &core.EntityMeta{ + CreatedTimestamp: timestamppb.Now(), + LastUpdatedTimestamp: timestamppb.Now(), + }, + } + + cachedFVs := make(map[string]map[string]*core.FeatureView) + cachedFVs["feature_repo"] = make(map[string]*core.FeatureView) + cachedFVs["feature_repo"]["fv1"] = fv + + cachedEntities := make(map[string]map[string]*core.Entity) + cachedEntities["feature_repo"] = make(map[string]*core.Entity) + cachedEntities["feature_repo"]["entity1"] = entity1 + cachedEntities["feature_repo"]["entity2"] = entity2 + + s.fs.Registry().CachedFeatureViews = cachedFVs + s.fs.Registry().CachedEntities = cachedEntities + + req, _ := http.NewRequest("POST", "/get-online-features", strings.NewReader(jsonRequest)) + rr := httptest.NewRecorder() + + s.getOnlineFeatures(rr, req) + + assert.Equal(t, http.StatusInternalServerError, rr.Code) +} + +func TestGetOnlineFeaturesWithValidFeatureService(t *testing.T) { + s := NewHttpServer(nil, nil) + + config := feast.GetRepoConfig() + s.fs, _ = feast.NewFeatureStore(&config, nil) + + jsonRequest := `{ + "feature_service": "fs1", + "entities": { + "join_key_1": [1, 2], + "join_key_2": ["value1", "value2"] + } + }` + + fv := &core.FeatureView{ + Spec: &core.FeatureViewSpec{ + Name: "fv1", + Features: []*core.FeatureSpecV2{ + { + Name: "feat1", + ValueType: types.ValueType_INT64, + }, + { + Name: "feat2", + ValueType: types.ValueType_STRING, + }, + }, + Ttl: &durationpb.Duration{ + Seconds: 3600, // 1 hour + Nanos: 0, + }, + Entities: []string{"entity1", "entity2"}, + }, + } + + entity1 := &core.Entity{ + Spec: &core.EntitySpecV2{ + Name: "entity1", + Project: "feature_repo", + ValueType: types.ValueType_INT32, + Description: "This is a sample entity", + JoinKey: "join_key_1", + Tags: map[string]string{ + "tag1": "value1", + "tag2": "value2", + }, + Owner: "sample_owner", + }, + Meta: &core.EntityMeta{ + CreatedTimestamp: timestamppb.Now(), + LastUpdatedTimestamp: timestamppb.Now(), + }, + } + + entity2 := &core.Entity{ + Spec: &core.EntitySpecV2{ + Name: "entity2", + Project: "feature_repo", + ValueType: types.ValueType_STRING, + Description: "This is a sample entity", + JoinKey: "join_key_2", + Tags: map[string]string{ + "tag1": "value1", + "tag2": "value2", + }, + Owner: "sample_owner", + }, + Meta: &core.EntityMeta{ + CreatedTimestamp: timestamppb.Now(), + LastUpdatedTimestamp: timestamppb.Now(), + }, + } + + featureService := &core.FeatureService{ + Spec: &core.FeatureServiceSpec{ + Name: "fs1", + Project: "feature_repo", + Description: "This is a sample feature service", + Owner: "sample_owner", + Features: []*core.FeatureViewProjection{ + { + FeatureViewName: "fv1", + FeatureColumns: []*core.FeatureSpecV2{ + { + Name: "feat1", + ValueType: types.ValueType_INT64, + }, + { + Name: "feat2", + ValueType: types.ValueType_STRING, + }, + }, + //JoinKeyMap: map[string]string{ + // "join_key_1": "", + // "join_key_2": "", + //}, + }, + }, + }, + Meta: &core.FeatureServiceMeta{ + CreatedTimestamp: timestamppb.Now(), + LastUpdatedTimestamp: timestamppb.Now(), + }, + } + + cachedFVs := make(map[string]map[string]*core.FeatureView) + cachedFVs["feature_repo"] = make(map[string]*core.FeatureView) + cachedFVs["feature_repo"]["fv1"] = fv + + cachedEntities := make(map[string]map[string]*core.Entity) + cachedEntities["feature_repo"] = make(map[string]*core.Entity) + cachedEntities["feature_repo"]["entity1"] = entity1 + cachedEntities["feature_repo"]["entity2"] = entity2 + + cachedFSs := make(map[string]map[string]*core.FeatureService) + cachedFSs["feature_repo"] = make(map[string]*core.FeatureService) + cachedFSs["feature_repo"]["fs1"] = featureService + + s.fs.Registry().CachedFeatureViews = cachedFVs + s.fs.Registry().CachedFeatureServices = cachedFSs + s.fs.Registry().CachedEntities = cachedEntities + + req, _ := http.NewRequest("POST", "/get-online-features", strings.NewReader(jsonRequest)) + rr := httptest.NewRecorder() + + s.getOnlineFeatures(rr, req) + + // Retrieve connection error string (as currently there's no mock for OnlineStore) + bodyBytes, _ := io.ReadAll(rr.Body) + bodyString := string(bodyBytes) + + // Error is only due to connection error resulting from not mocking + assert.Equal(t, http.StatusInternalServerError, rr.Code) + strings.Contains(bodyString, "connection refused") + +} + +func TestGetOnlineFeaturesWithInvalidFeatureService(t *testing.T) { + s := NewHttpServer(nil, nil) + + config := feast.GetRepoConfig() + s.fs, _ = feast.NewFeatureStore(&config, nil) + + jsonRequest := `{ + "feature_service": "invalid_fs", + "entities": { + "join_key_1": [1, 2], + "join_key_2": ["value1", "value2"] + } + }` + + fv := &core.FeatureView{ + Spec: &core.FeatureViewSpec{ + Name: "fv1", + Features: []*core.FeatureSpecV2{ + { + Name: "feat1", + ValueType: types.ValueType_INT64, + }, + { + Name: "feat2", + ValueType: types.ValueType_STRING, + }, + }, + Ttl: &durationpb.Duration{ + Seconds: 3600, // 1 hour + Nanos: 0, + }, + Entities: []string{"entity1", "entity2"}, + }, + } + + entity1 := &core.Entity{ + Spec: &core.EntitySpecV2{ + Name: "entity1", + Project: "feature_repo", + ValueType: types.ValueType_INT32, + Description: "This is a sample entity", + JoinKey: "join_key_1", + Tags: map[string]string{ + "tag1": "value1", + "tag2": "value2", + }, + Owner: "sample_owner", + }, + Meta: &core.EntityMeta{ + CreatedTimestamp: timestamppb.Now(), + LastUpdatedTimestamp: timestamppb.Now(), + }, + } + + entity2 := &core.Entity{ + Spec: &core.EntitySpecV2{ + Name: "entity2", + Project: "feature_repo", + ValueType: types.ValueType_STRING, + Description: "This is a sample entity", + JoinKey: "join_key_2", + Tags: map[string]string{ + "tag1": "value1", + "tag2": "value2", + }, + Owner: "sample_owner", + }, + Meta: &core.EntityMeta{ + CreatedTimestamp: timestamppb.Now(), + LastUpdatedTimestamp: timestamppb.Now(), + }, + } + + featureService := &core.FeatureService{ + Spec: &core.FeatureServiceSpec{ + Name: "fs1", + Project: "feature_repo", + Description: "This is a sample feature service", + Owner: "sample_owner", + Features: []*core.FeatureViewProjection{ + { + FeatureViewName: "fv1", + FeatureColumns: []*core.FeatureSpecV2{ + { + Name: "feat1", + ValueType: types.ValueType_INT64, + }, + { + Name: "feat2", + ValueType: types.ValueType_STRING, + }, + }, + //JoinKeyMap: map[string]string{ + // "join_key_1": "", + // "join_key_2": "", + //}, + }, + }, + }, + Meta: &core.FeatureServiceMeta{ + CreatedTimestamp: timestamppb.Now(), + LastUpdatedTimestamp: timestamppb.Now(), + }, + } + + cachedFVs := make(map[string]map[string]*core.FeatureView) + cachedFVs["feature_repo"] = make(map[string]*core.FeatureView) + cachedFVs["feature_repo"]["fv1"] = fv + + cachedEntities := make(map[string]map[string]*core.Entity) + cachedEntities["feature_repo"] = make(map[string]*core.Entity) + cachedEntities["feature_repo"]["entity1"] = entity1 + cachedEntities["feature_repo"]["entity2"] = entity2 + + cachedFSs := make(map[string]map[string]*core.FeatureService) + cachedFSs["feature_repo"] = make(map[string]*core.FeatureService) + cachedFSs["feature_repo"]["fs1"] = featureService + + s.fs.Registry().CachedFeatureViews = cachedFVs + s.fs.Registry().CachedFeatureServices = cachedFSs + s.fs.Registry().CachedEntities = cachedEntities + + req, _ := http.NewRequest("POST", "/get-online-features", strings.NewReader(jsonRequest)) + rr := httptest.NewRecorder() + + s.getOnlineFeatures(rr, req) + + // Retrieve error string + bodyBytes, _ := io.ReadAll(rr.Body) + bodyString := string(bodyBytes) + + assert.Equal(t, http.StatusInternalServerError, rr.Code) + assert.Equal(t, strings.Contains(bodyString, "no cached feature service"), true) +} + +func TestGetOnlineFeaturesWithInvalidEntities(t *testing.T) { + s := NewHttpServer(nil, nil) + + config := feast.GetRepoConfig() + s.fs, _ = feast.NewFeatureStore(&config, nil) + + jsonRequest := `{ + "features": ["fv1:feat1", "fv1:feat2"], + "entities": { + "join_key_invalid": [1, 2], + "join_key_2": ["value1", "value2"] + } + }` + + fv := &core.FeatureView{ + Spec: &core.FeatureViewSpec{ + Name: "fv1", + Features: []*core.FeatureSpecV2{ + { + Name: "feat1", + ValueType: types.ValueType_INT64, + }, + { + Name: "feat2", + ValueType: types.ValueType_STRING, + }, + }, + Ttl: &durationpb.Duration{ + Seconds: 3600, // 1 hour + Nanos: 0, + }, + Entities: []string{"entity1", "entity2"}, + }, + } + + entity1 := &core.Entity{ + Spec: &core.EntitySpecV2{ + Name: "entity1", + Project: "feature_repo", + ValueType: types.ValueType_INT32, + Description: "This is a sample entity", + JoinKey: "join_key_1", + Tags: map[string]string{ + "tag1": "value1", + "tag2": "value2", + }, + Owner: "sample_owner", + }, + Meta: &core.EntityMeta{ + CreatedTimestamp: timestamppb.Now(), + LastUpdatedTimestamp: timestamppb.Now(), + }, + } + + entity2 := &core.Entity{ + Spec: &core.EntitySpecV2{ + Name: "entity2", + Project: "feature_repo", + ValueType: types.ValueType_STRING, + Description: "This is a sample entity", + JoinKey: "join_key_2", + Tags: map[string]string{ + "tag1": "value1", + "tag2": "value2", + }, + Owner: "sample_owner", + }, + Meta: &core.EntityMeta{ + CreatedTimestamp: timestamppb.Now(), + LastUpdatedTimestamp: timestamppb.Now(), + }, + } + + cachedFVs := make(map[string]map[string]*core.FeatureView) + cachedFVs["feature_repo"] = make(map[string]*core.FeatureView) + cachedFVs["feature_repo"]["fv1"] = fv + + cachedEntities := make(map[string]map[string]*core.Entity) + cachedEntities["feature_repo"] = make(map[string]*core.Entity) + cachedEntities["feature_repo"]["entity1"] = entity1 + cachedEntities["feature_repo"]["entity2"] = entity2 + + s.fs.Registry().CachedFeatureViews = cachedFVs + s.fs.Registry().CachedEntities = cachedEntities + + req, _ := http.NewRequest("POST", "/get-online-features", strings.NewReader(jsonRequest)) + rr := httptest.NewRecorder() + + s.getOnlineFeatures(rr, req) + + // Retrieve error string + bodyBytes, _ := io.ReadAll(rr.Body) + bodyString := string(bodyBytes) + + assert.Equal(t, http.StatusNotFound, rr.Code) + assert.Equal(t, strings.Contains(bodyString, "Entity with key join_key_invalid not found"), true) } -func TestMarshalInt64JSON(t *testing.T) { - var arrowArray arrow.Array - memoryPool := memory.NewGoAllocator() - builder := array.NewInt64Builder(memoryPool) - defer builder.Release() - builder.AppendValues([]int64{-9223372036854775808, 9223372036854775807}, nil) - arrowArray = builder.NewArray() - defer arrowArray.Release() - expectedJSON := `[-9223372036854775808,9223372036854775807]` - - jsonData, err := json.Marshal(arrowArray) - assert.NoError(t, err, "Error marshaling Arrow array") - - assert.Equal(t, expectedJSON, string(jsonData), "JSON output does not match expected") - assert.IsType(t, &array.Int64{}, arrowArray, "arrowArray is not of type *array.Int64") +func TestGetOnlineFeaturesWithEntities(t *testing.T) { + s := NewHttpServer(nil, nil) + + config := feast.GetRepoConfig() + s.fs, _ = feast.NewFeatureStore(&config, nil) + + jsonRequest := `{ + "features": ["odfv1:feat1"], + "entities": { + "join_key_1": [1, 2], + "rq_field": [1, 2] + } + }` + + fv := &core.FeatureView{ + Spec: &core.FeatureViewSpec{ + Name: "fv1", + Features: []*core.FeatureSpecV2{ + { + Name: "feat1", + ValueType: types.ValueType_INT64, + }, + { + Name: "feat2", + ValueType: types.ValueType_STRING, + }, + }, + Ttl: &durationpb.Duration{ + Seconds: 3600, // 1 hour + Nanos: 0, + }, + Entities: []string{"entity1"}, + }, + } + + odfv := &core.OnDemandFeatureView{ + Spec: &core.OnDemandFeatureViewSpec{ + Name: "odfv1", + Project: "feature_repo", + Features: []*core.FeatureSpecV2{ + { + Name: "feat1", + ValueType: types.ValueType_INT64, + }, + { + Name: "feat2", + ValueType: types.ValueType_INT64, + }, + }, + Sources: map[string]*core.OnDemandSource{ + "rqsource1": { + Source: &core.OnDemandSource_RequestDataSource{ + RequestDataSource: &core.DataSource{ + Name: "rqsource1", + Type: core.DataSource_REQUEST_SOURCE, + Options: &core.DataSource_RequestDataOptions_{ + RequestDataOptions: &core.DataSource_RequestDataOptions{ + Schema: []*core.FeatureSpecV2{ + { + Name: "rq_field", + ValueType: types.ValueType_INT64, + }, + }, + }, + }, + }, + }, + }, + "fv1": { + Source: &core.OnDemandSource_FeatureView{ + FeatureView: &core.FeatureView{ + Spec: &core.FeatureViewSpec{ + Name: "fv1", + Features: []*core.FeatureSpecV2{ + { + Name: "feat1", + ValueType: types.ValueType_INT64, + }, + { + Name: "feat2", + ValueType: types.ValueType_STRING, + }, + }, + Ttl: &durationpb.Duration{ + Seconds: 3600, // 1 hour + Nanos: 0, + }, + Entities: []string{"entity1"}, + }, + }, + }, + }, + }, + FeatureTransformation: &core.FeatureTransformationV2{ + Transformation: &core.FeatureTransformationV2_UserDefinedFunction{ + UserDefinedFunction: &core.UserDefinedFunctionV2{ + Name: "Sample User Defined Function V2", + Body: []byte("function body"), + BodyText: "function body text", + }, + }, + }, + }, + } + + entity1 := &core.Entity{ + Spec: &core.EntitySpecV2{ + Name: "entity1", + Project: "feature_repo", + ValueType: types.ValueType_INT32, + Description: "This is a sample entity", + JoinKey: "join_key_1", + Tags: map[string]string{ + "tag1": "value1", + "tag2": "value2", + }, + Owner: "sample_owner", + }, + Meta: &core.EntityMeta{ + CreatedTimestamp: timestamppb.Now(), + LastUpdatedTimestamp: timestamppb.Now(), + }, + } + + cachedODFVs := make(map[string]map[string]*core.OnDemandFeatureView) + cachedODFVs["feature_repo"] = make(map[string]*core.OnDemandFeatureView) + cachedODFVs["feature_repo"]["odfv1"] = odfv + + cachedFVs := make(map[string]map[string]*core.FeatureView) + cachedFVs["feature_repo"] = make(map[string]*core.FeatureView) + cachedFVs["feature_repo"]["odfv1"] = fv + + cachedEntities := make(map[string]map[string]*core.Entity) + cachedEntities["feature_repo"] = make(map[string]*core.Entity) + cachedEntities["feature_repo"]["entity1"] = entity1 + + s.fs.Registry().CachedOnDemandFeatureViews = cachedODFVs + s.fs.Registry().CachedFeatureViews = cachedFVs + s.fs.Registry().CachedEntities = cachedEntities + + req, _ := http.NewRequest("POST", "/get-online-features", strings.NewReader(jsonRequest)) + rr := httptest.NewRecorder() + + s.getOnlineFeatures(rr, req) + + // Retrieve connection error string (as currently there's no mock for OnlineStore) + bodyBytes, _ := io.ReadAll(rr.Body) + bodyString := string(bodyBytes) + + // Error is only due to connection error resulting from not mocking + assert.Equal(t, http.StatusInternalServerError, rr.Code) + assert.Equal(t, strings.Contains(bodyString, "connection refused"), true) +} + +func TestGetOnlineFeaturesWithRequestContextOnly(t *testing.T) { + + s := NewHttpServer(nil, nil) + + config := feast.GetRepoConfig() + s.fs, _ = feast.NewFeatureStore(&config, nil) + + jsonRequest := `{ + "features": ["odfv1:feat1"], + "entities": { + "join_key_1": [1, 2] + }, + "request_context": { + "rq_field": [1, 2] + } + }` + + fv := &core.FeatureView{ + Spec: &core.FeatureViewSpec{ + Name: "fv1", + Features: []*core.FeatureSpecV2{ + { + Name: "feat1", + ValueType: types.ValueType_INT64, + }, + { + Name: "feat2", + ValueType: types.ValueType_STRING, + }, + }, + Ttl: &durationpb.Duration{ + Seconds: 3600, // 1 hour + Nanos: 0, + }, + Entities: []string{"entity1"}, + }, + } + + odfv := &core.OnDemandFeatureView{ + Spec: &core.OnDemandFeatureViewSpec{ + Name: "odfv1", + Project: "feature_repo", + Features: []*core.FeatureSpecV2{ + { + Name: "feat1", + ValueType: types.ValueType_INT64, + }, + { + Name: "feat2", + ValueType: types.ValueType_INT64, + }, + }, + Sources: map[string]*core.OnDemandSource{ + "rqsource1": { + Source: &core.OnDemandSource_RequestDataSource{ + RequestDataSource: &core.DataSource{ + Name: "rqsource1", + Type: core.DataSource_REQUEST_SOURCE, + Options: &core.DataSource_RequestDataOptions_{ + RequestDataOptions: &core.DataSource_RequestDataOptions{ + Schema: []*core.FeatureSpecV2{ + { + Name: "rq_field", + ValueType: types.ValueType_INT64, + }, + }, + }, + }, + }, + }, + }, + "fv1": { + Source: &core.OnDemandSource_FeatureView{ + FeatureView: &core.FeatureView{ + Spec: &core.FeatureViewSpec{ + Name: "fv1", + Features: []*core.FeatureSpecV2{ + { + Name: "feat1", + ValueType: types.ValueType_INT64, + }, + { + Name: "feat2", + ValueType: types.ValueType_STRING, + }, + }, + Ttl: &durationpb.Duration{ + Seconds: 3600, // 1 hour + Nanos: 0, + }, + Entities: []string{"entity1"}, + }, + }, + }, + }, + }, + FeatureTransformation: &core.FeatureTransformationV2{ + Transformation: &core.FeatureTransformationV2_UserDefinedFunction{ + UserDefinedFunction: &core.UserDefinedFunctionV2{ + Name: "Sample User Defined Function V2", + Body: []byte("function body"), + BodyText: "function body text", + }, + }, + }, + }, + } + + entity1 := &core.Entity{ + Spec: &core.EntitySpecV2{ + Name: "entity1", + Project: "feature_repo", + ValueType: types.ValueType_INT32, + Description: "This is a sample entity", + JoinKey: "join_key_1", + Tags: map[string]string{ + "tag1": "value1", + "tag2": "value2", + }, + Owner: "sample_owner", + }, + Meta: &core.EntityMeta{ + CreatedTimestamp: timestamppb.Now(), + LastUpdatedTimestamp: timestamppb.Now(), + }, + } + + cachedODFVs := make(map[string]map[string]*core.OnDemandFeatureView) + cachedODFVs["feature_repo"] = make(map[string]*core.OnDemandFeatureView) + cachedODFVs["feature_repo"]["odfv1"] = odfv + + cachedFVs := make(map[string]map[string]*core.FeatureView) + cachedFVs["feature_repo"] = make(map[string]*core.FeatureView) + cachedFVs["feature_repo"]["odfv1"] = fv + + cachedEntities := make(map[string]map[string]*core.Entity) + cachedEntities["feature_repo"] = make(map[string]*core.Entity) + cachedEntities["feature_repo"]["entity1"] = entity1 + + s.fs.Registry().CachedOnDemandFeatureViews = cachedODFVs + s.fs.Registry().CachedFeatureViews = cachedFVs + s.fs.Registry().CachedEntities = cachedEntities + + req, _ := http.NewRequest("POST", "/get-online-features", strings.NewReader(jsonRequest)) + rr := httptest.NewRecorder() + + s.getOnlineFeatures(rr, req) + + // Retrieve connection error string (as currently there's no mock for OnlineStore) + bodyBytes, _ := io.ReadAll(rr.Body) + bodyString := string(bodyBytes) + + // Error is only due to connection error resulting from not mocking + assert.Equal(t, http.StatusInternalServerError, rr.Code) + assert.Equal(t, strings.Contains(bodyString, "connection refused"), true) + +} + +func TestGetOnlineFeaturesWithInvalidRequestContext(t *testing.T) { + + s := NewHttpServer(nil, nil) + + config := feast.GetRepoConfig() + s.fs, _ = feast.NewFeatureStore(&config, nil) + + jsonRequest := `{ + "features": ["odfv1:feat1"], + "entities": { + "join_key_1": [1, 2] + }, + "request_context": { + "rq_field_1": [1, 2] + } + }` + + fv := &core.FeatureView{ + Spec: &core.FeatureViewSpec{ + Name: "fv1", + Features: []*core.FeatureSpecV2{ + { + Name: "feat1", + ValueType: types.ValueType_INT64, + }, + { + Name: "feat2", + ValueType: types.ValueType_STRING, + }, + }, + Ttl: &durationpb.Duration{ + Seconds: 3600, // 1 hour + Nanos: 0, + }, + Entities: []string{"entity1"}, + }, + } + + odfv := &core.OnDemandFeatureView{ + Spec: &core.OnDemandFeatureViewSpec{ + Name: "odfv1", + Project: "feature_repo", + Features: []*core.FeatureSpecV2{ + { + Name: "feat1", + ValueType: types.ValueType_INT64, + }, + { + Name: "feat2", + ValueType: types.ValueType_INT64, + }, + }, + Sources: map[string]*core.OnDemandSource{ + "rqsource1": { + Source: &core.OnDemandSource_RequestDataSource{ + RequestDataSource: &core.DataSource{ + Name: "rqsource1", + Type: core.DataSource_REQUEST_SOURCE, + Options: &core.DataSource_RequestDataOptions_{ + RequestDataOptions: &core.DataSource_RequestDataOptions{ + Schema: []*core.FeatureSpecV2{ + { + Name: "rq_field", + ValueType: types.ValueType_INT64, + }, + }, + }, + }, + }, + }, + }, + "fv1": { + Source: &core.OnDemandSource_FeatureView{ + FeatureView: &core.FeatureView{ + Spec: &core.FeatureViewSpec{ + Name: "fv1", + Features: []*core.FeatureSpecV2{ + { + Name: "feat1", + ValueType: types.ValueType_INT64, + }, + { + Name: "feat2", + ValueType: types.ValueType_STRING, + }, + }, + Ttl: &durationpb.Duration{ + Seconds: 3600, // 1 hour + Nanos: 0, + }, + Entities: []string{"entity1"}, + }, + }, + }, + }, + }, + FeatureTransformation: &core.FeatureTransformationV2{ + Transformation: &core.FeatureTransformationV2_UserDefinedFunction{ + UserDefinedFunction: &core.UserDefinedFunctionV2{ + Name: "Sample User Defined Function V2", + Body: []byte("function body"), + BodyText: "function body text", + }, + }, + }, + }, + } + + entity1 := &core.Entity{ + Spec: &core.EntitySpecV2{ + Name: "entity1", + Project: "feature_repo", + ValueType: types.ValueType_INT32, + Description: "This is a sample entity", + JoinKey: "join_key_1", + Tags: map[string]string{ + "tag1": "value1", + "tag2": "value2", + }, + Owner: "sample_owner", + }, + Meta: &core.EntityMeta{ + CreatedTimestamp: timestamppb.Now(), + LastUpdatedTimestamp: timestamppb.Now(), + }, + } + + cachedODFVs := make(map[string]map[string]*core.OnDemandFeatureView) + cachedODFVs["feature_repo"] = make(map[string]*core.OnDemandFeatureView) + cachedODFVs["feature_repo"]["odfv1"] = odfv + + cachedFVs := make(map[string]map[string]*core.FeatureView) + cachedFVs["feature_repo"] = make(map[string]*core.FeatureView) + cachedFVs["feature_repo"]["odfv1"] = fv + + cachedEntities := make(map[string]map[string]*core.Entity) + cachedEntities["feature_repo"] = make(map[string]*core.Entity) + cachedEntities["feature_repo"]["entity1"] = entity1 + + s.fs.Registry().CachedOnDemandFeatureViews = cachedODFVs + s.fs.Registry().CachedFeatureViews = cachedFVs + s.fs.Registry().CachedEntities = cachedEntities + + req, _ := http.NewRequest("POST", "/get-online-features", strings.NewReader(jsonRequest)) + rr := httptest.NewRecorder() + + s.getOnlineFeatures(rr, req) + + bodyBytes, _ := io.ReadAll(rr.Body) + bodyString := string(bodyBytes) + + assert.Equal(t, http.StatusNotFound, rr.Code) + assert.Equal(t, strings.Contains(bodyString, "Request Source rq_field_1 not found"), true) + } diff --git a/go/internal/feast/test_utils.go b/go/internal/feast/test_utils.go new file mode 100644 index 0000000000..8870db0b9f --- /dev/null +++ b/go/internal/feast/test_utils.go @@ -0,0 +1,32 @@ +package feast + +import ( + "github.com/feast-dev/feast/go/internal/feast/registry" + "path/filepath" + "runtime" +) + +func GetRepoConfig() (config registry.RepoConfig) { + return registry.RepoConfig{ + Project: "feature_repo", + Registry: getRegistryPath(), + Provider: "local", + OnlineStore: map[string]interface{}{ + "type": "redis", + "connection_string": "localhost:6379", + }, + } +} + +// Return absolute path to the test_repo registry regardless of the working directory +func getRegistryPath() map[string]interface{} { + // Get the file path of this source file, regardless of the working directory + _, filename, _, ok := runtime.Caller(0) + if !ok { + panic("couldn't find file path of the test file") + } + registry := map[string]interface{}{ + "path": filepath.Join(filename, "..", "..", "..", "feature_repo/data/registry.db"), + } + return registry +}