Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ require (
github.com/gogo/protobuf v1.3.1 // indirect
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect
github.com/golang/mock v1.2.0
github.com/golang/protobuf v1.4.3
github.com/google/go-cmp v0.5.0
github.com/golang/protobuf v1.5.2
github.com/google/go-cmp v0.5.6
github.com/huandu/xstrings v1.2.0 // indirect
github.com/lyft/protoc-gen-validate v0.1.0 // indirect
github.com/mitchellh/copystructure v1.0.0 // indirect
Expand All @@ -23,10 +23,12 @@ require (
github.com/woop/protoc-gen-doc v1.3.0 // indirect
go.opencensus.io v0.22.3 // indirect
golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect
golang.org/x/net v0.0.0-20201021035429-f5854403a974
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6 // indirect
golang.org/x/tools v0.0.0-20201124165954-ed677e9dcd1e // indirect
google.golang.org/grpc v1.29.1
google.golang.org/protobuf v1.25.0 // indirect
google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3 // indirect
google.golang.org/grpc v1.46.0
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.2.0 // indirect
gopkg.in/russross/blackfriday.v2 v2.0.0 // indirect
gopkg.in/yaml.v2 v2.2.4
istio.io/gogo-genproto v0.0.0-20191212213402-78a529a42cd8 // indirect
Expand Down
62 changes: 43 additions & 19 deletions protos/feast/serving/ServingService.proto
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ service ServingService {

// Get online features (v2) synchronously.
rpc GetOnlineFeaturesV2 (GetOnlineFeaturesRequestV2) returns (GetOnlineFeaturesResponse);

// Get online features using optimized response message.
rpc GetOnlineFeatures (GetOnlineFeaturesRequestV2) returns (GetOnlineFeaturesResponseV2);
}

message GetFeastServingInfoRequest {}
Expand Down Expand Up @@ -92,30 +95,51 @@ message GetOnlineFeaturesResponse {
// Map of feature or entity name to feature/entity statuses/metadata.
map<string, FieldStatus> statuses = 2;
}

enum FieldStatus {
// Status is unset for this field.
INVALID = 0;
}

// Field value is present for this field and age is within max age.
PRESENT = 1;
message GetOnlineFeaturesResponseV2 {
GetOnlineFeaturesResponseMetadata metadata = 1;

// Values could be found for entity key and age is within max age, but
// this field value is assigned a value on ingestion into feast.
NULL_VALUE = 2;
// Length of "results" array should match length of requested features and entities.
// We also preserve the same order of features here as in metadata.field_names
repeated FieldVector results = 2;

// Entity key did not return any values as they do not exist in Feast.
// This could suggest that the feature values have not yet been ingested
// into feast or the ingestion failed.
NOT_FOUND = 3;
message FieldVector {
repeated feast.types.Value values = 1;
repeated FieldStatus statuses = 2;
}
}

// Values could be found for entity key, but field values are outside the maximum
// allowable range.
OUTSIDE_MAX_AGE = 4;
message GetOnlineFeaturesResponseMetadata {
FieldList field_names = 1;
}

// Values could be found for entity key, but are null and is due to ingestion failures
INGESTION_FAILURE = 5;
}
message FieldList {
repeated string val = 1;
}

enum FieldStatus {
// Status is unset for this field.
INVALID = 0;

// Field value is present for this field and age is within max age.
PRESENT = 1;

// Values could be found for entity key and age is within max age, but
// this field value is assigned a value on ingestion into feast.
NULL_VALUE = 2;

// Entity key did not return any values as they do not exist in Feast.
// This could suggest that the feature values have not yet been ingested
// into feast or the ingestion failed.
NOT_FOUND = 3;

// Values could be found for entity key, but field values are outside the maximum
// allowable range.
OUTSIDE_MAX_AGE = 4;

// Values could be found for entity key, but are null and is due to ingestion failures
INGESTION_FAILURE = 5;
}

enum FeastServingType {
Expand Down
4 changes: 2 additions & 2 deletions sdk/go/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,9 @@ func (fc *GrpcClient) GetOnlineFeatures(ctx context.Context, req *OnlineFeatures
if err != nil {
return nil, err
}
resp, err := fc.cli.GetOnlineFeaturesV2(ctx, featuresRequest)
resp, err := fc.cli.GetOnlineFeatures(ctx, featuresRequest)

// collect unqiue entity refs from entity rows
// collect unique entity refs from entity rows
entityRefs := make(map[string]struct{})
for _, entityRows := range req.Entities {
for ref := range entityRows {
Expand Down
33 changes: 22 additions & 11 deletions sdk/go/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ func TestGetOnlineFeatures(t *testing.T) {
tt := []struct {
name string
req OnlineFeaturesRequest
recieve OnlineFeaturesResponse
receive OnlineFeaturesResponse
want OnlineFeaturesResponse
wantErr bool
err error
Expand All @@ -33,16 +33,27 @@ func TestGetOnlineFeatures(t *testing.T) {
Project: "driver_project",
},
want: OnlineFeaturesResponse{
RawResponse: &serving.GetOnlineFeaturesResponse{
FieldValues: []*serving.GetOnlineFeaturesResponse_FieldValues{
RawResponse: &serving.GetOnlineFeaturesResponseV2{
Metadata: &serving.GetOnlineFeaturesResponseMetadata{
FieldNames: &serving.FieldList{
Val: []string{
"driver_id",
"driver:rating",
"driver:null_value",
},
},
},
Results: []*serving.GetOnlineFeaturesResponseV2_FieldVector{
{
Fields: map[string]*types.Value{
"driver:rating": Int64Val(1),
"driver:null_value": {},
Values: []*types.Value{
Int64Val(1),
Int64Val(1),
{},
},
Statuses: map[string]serving.GetOnlineFeaturesResponse_FieldStatus{
"driver:rating": serving.GetOnlineFeaturesResponse_PRESENT,
"driver:null_value": serving.GetOnlineFeaturesResponse_NULL_VALUE,
Statuses: []serving.FieldStatus{
serving.FieldStatus_PRESENT,
serving.FieldStatus_PRESENT,
serving.FieldStatus_NULL_VALUE,
},
},
},
Expand All @@ -53,14 +64,14 @@ func TestGetOnlineFeatures(t *testing.T) {

for _, tc := range tt {
t.Run(tc.name, func(t *testing.T) {
// mock feast grpc client get online feature requestss
// mock feast grpc client get online feature requests
ctrl := gomock.NewController(t)
defer ctrl.Finish()
cli := mock_serving.NewMockServingServiceClient(ctrl)
ctx := context.Background()
rawRequest, _ := tc.req.buildRequest()
resp := tc.want.RawResponse
cli.EXPECT().GetOnlineFeaturesV2(ctx, rawRequest).Return(resp, nil).Times(1)
cli.EXPECT().GetOnlineFeatures(ctx, rawRequest).Return(resp, nil).Times(1)

client := &GrpcClient{
cli: cli,
Expand Down
2 changes: 1 addition & 1 deletion sdk/go/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ require (
go.opencensus.io v0.22.4
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
google.golang.org/api v0.30.0
google.golang.org/grpc v1.31.0
google.golang.org/grpc v1.32.0
google.golang.org/protobuf v1.25.0
)
Loading