Skip to content

Commit 473e0af

Browse files
authored
Create empty Job Service (feast-dev#1059)
* Create empty Job Service Signed-off-by: Tsotne Tabidze <tsotnet@gmail.com> * Reintroduce accidentally removed functions in JobServiceServicer Signed-off-by: Tsotne Tabidze <tsotnet@gmail.com>
1 parent b16f2bb commit 473e0af

10 files changed

Lines changed: 379 additions & 17 deletions

File tree

.dockerignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
docs
22
!docs/coverage
33
charts
4+
env

Makefile

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ build-java-no-tests:
6161
# Python SDK
6262

6363
install-python-ci-dependencies:
64-
pip install -r sdk/python/requirements-ci.txt
64+
pip install --no-cache-dir -r sdk/python/requirements-ci.txt
6565

6666
compile-protos-python: install-python-ci-dependencies
6767
@$(foreach dir,$(PROTO_TYPE_SUBDIRS),cd ${ROOT_DIR}/protos; python -m grpc_tools.protoc -I. --python_out=../sdk/python/ --mypy_out=../sdk/python/ feast/$(dir)/*.proto;)
@@ -121,15 +121,19 @@ build-push-docker:
121121
@$(MAKE) push-serving-docker registry=$(REGISTRY) version=$(VERSION)
122122
@$(MAKE) push-ci-docker registry=$(REGISTRY) version=$(VERSION)
123123
@$(MAKE) push-jobcontroller-docker registry=$(REGISTRY) version=$(VERSION)
124+
@$(MAKE) push-jobservice-docker registry=$(REGISTRY) version=$(VERSION)
124125

125-
build-docker: build-core-docker build-serving-docker build-ci-docker build-jobcontroller-docker
126+
build-docker: build-core-docker build-serving-docker build-ci-docker build-jobcontroller-docker build-jobservice-docker
126127

127128
push-core-docker:
128129
docker push $(REGISTRY)/feast-core:$(VERSION)
129130

130131
push-jobcontroller-docker:
131132
docker push $(REGISTRY)/feast-jobcontroller:$(VERSION)
132133

134+
push-jobservice-docker:
135+
docker push $(REGISTRY)/feast-jobservice:$(VERSION)
136+
133137
push-serving-docker:
134138
docker push $(REGISTRY)/feast-serving:$(VERSION)
135139

@@ -142,6 +146,9 @@ push-jupyter-docker:
142146
build-core-docker:
143147
docker build -t $(REGISTRY)/feast-core:$(VERSION) -f infra/docker/core/Dockerfile .
144148

149+
build-jobservice-docker:
150+
docker build -t $(REGISTRY)/feast-jobservice:$(VERSION) -f infra/docker/jobservice/Dockerfile .
151+
145152
build-jobcontroller-docker:
146153
docker build -t $(REGISTRY)/feast-jobcontroller:$(VERSION) -f infra/docker/jobcontroller/Dockerfile .
147154

@@ -200,4 +207,4 @@ lint-versions:
200207
# Performance
201208

202209
test-load:
203-
./infra/scripts/test-load.sh $(GIT_SHA)
210+
./infra/scripts/test-load.sh $(GIT_SHA)

infra/docker/jobservice/Dockerfile

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
FROM python:3.7-slim-buster
2+
3+
USER root
4+
WORKDIR /feast
5+
6+
COPY sdk/python sdk/python
7+
COPY Makefile Makefile
8+
COPY protos protos
9+
10+
# Install make
11+
RUN apt-get update && apt-get -y install make git
12+
13+
# Install Python dependencies
14+
RUN make compile-protos-python
15+
16+
# Install Feast SDK
17+
COPY .git .git
18+
COPY README.md README.md
19+
RUN pip install -e sdk/python -U
20+
21+
CMD ["feast", "server"]

protos/feast/core/JobService.proto

Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
//
2+
// Copyright 2018 The Feast Authors
3+
//
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
//
8+
// https://www.apache.org/licenses/LICENSE-2.0
9+
//
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS,
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
//
16+
17+
syntax = "proto3";
18+
package feast.core;
19+
20+
option go_package = "github.com/feast-dev/feast/sdk/go/protos/feast/core";
21+
option java_outer_classname = "JobServiceProto";
22+
option java_package = "feast.proto.core";
23+
24+
import "google/protobuf/timestamp.proto";
25+
import "feast/core/DataSource.proto";
26+
import "feast/serving/ServingService.proto";
27+
28+
service JobService {
29+
// Start job to ingest data from offline store into online store
30+
rpc StartOfflineToOnlineIngestionJob (StartOfflineToOnlineIngestionJobRequest) returns (StartOfflineToOnlineIngestionJobResponse);
31+
32+
// Produce a training dataset, return a job id that will provide a file reference
33+
rpc GetHistoricalFeatures (GetHistoricalFeaturesRequest) returns (GetHistoricalFeaturesResponse);
34+
35+
// Start job to ingest data from stream into online store
36+
rpc StartStreamToOnlineIngestionJob (StartStreamToOnlineIngestionJobRequest) returns (StartStreamToOnlineIngestionJobResponse);
37+
38+
// List all types of jobs
39+
rpc ListJobs (ListJobsRequest) returns (ListJobsResponse);
40+
41+
// Stop a single job
42+
rpc StopJob (StopJobRequest) returns (StopJobResponse);
43+
44+
// Get details of a single job
45+
rpc GetJob (GetJobRequest) returns (GetJobResponse);
46+
}
47+
48+
49+
enum JobType {
50+
INVALID_JOB = 0;
51+
OFFLINE_TO_ONLINE_JOB = 1;
52+
STREAM_TO_ONLINE_JOB = 2;
53+
EXPORT_JOB = 4;
54+
}
55+
56+
enum JobStatus {
57+
JOB_STATUS_INVALID = 0;
58+
// The Job has be registered and waiting to get scheduled to run
59+
JOB_STATUS_PENDING = 1;
60+
// The Job is currently processing its task
61+
JOB_STATUS_RUNNING = 2;
62+
// The Job has successfully completed its task
63+
JOB_STATUS_DONE = 3;
64+
// The Job has encountered an error while processing its task
65+
JOB_STATUS_ERROR = 4;
66+
}
67+
68+
message Job {
69+
// Identifier of the Job
70+
string id = 1;
71+
// External Identifier of the Job assigned by the Spark executor
72+
string external_id = 2;
73+
// Type of the Job
74+
JobType type = 3;
75+
// Current job status
76+
JobStatus status = 4;
77+
// Timestamp on when the job was is created
78+
google.protobuf.Timestamp created_timestamp = 5;
79+
// Timestamp on when the job has stopped.
80+
google.protobuf.Timestamp stop_timestamp = 6;
81+
82+
message ExportJobMeta {
83+
// Glob of the exported files that should be retrieved to reconstruct
84+
// the dataframe with retrieved features.
85+
repeated string file_glob = 1;
86+
// The Historical Features request that triggered this export job
87+
GetHistoricalFeaturesRequest request = 2;
88+
}
89+
90+
message OfflineToOnlineMeta {
91+
// Reference to the Feature Table being populated by this job
92+
string project = 1;
93+
string table_name = 2;
94+
}
95+
96+
message StreamToOnlineMeta {
97+
// Reference to the Feature Table being populated by this job
98+
string project = 1;
99+
string table_name = 2;
100+
}
101+
102+
// JobType specific metadata on the job
103+
oneof meta {
104+
ExportJobMeta export = 7;
105+
OfflineToOnlineMeta offline_to_online = 8;
106+
StreamToOnlineMeta stream_to_online = 9;
107+
}
108+
}
109+
110+
// Ingest data from offline store into online store
111+
message StartOfflineToOnlineIngestionJobRequest {
112+
// Feature table to ingest
113+
string project = 1;
114+
string table_name = 2;
115+
116+
// Start of time range for source data from offline store
117+
google.protobuf.Timestamp start_date = 3;
118+
119+
// End of time range for source data from offline store
120+
google.protobuf.Timestamp end_date = 4;
121+
}
122+
123+
message StartOfflineToOnlineIngestionJobResponse {
124+
// Job ID assigned by Feast
125+
string id = 1;
126+
}
127+
128+
message GetHistoricalFeaturesRequest {
129+
// List of features that are being retrieved
130+
repeated feast.serving.FeatureReferenceV2 features = 1;
131+
132+
// Batch DataSource that can be used to obtain entity values for historical retrieval.
133+
// For each entity value, a feature value will be retrieved for that value/timestamp
134+
// Only 'BATCH_*' source types are supported.
135+
// Currently only BATCH_FILE source type is supported.
136+
DataSource entities_source = 2;
137+
138+
// Optional field to specify project name override. If specified, uses the
139+
// given project for retrieval. Overrides the projects specified in
140+
// Feature References if both are specified.
141+
string project = 3;
142+
143+
// Specifies the path in a bucket to write the exported feature data files
144+
// Export to AWS S3 - s3://path/to/features
145+
// Export to GCP GCS - gs://path/to/features
146+
string destination_path = 4;
147+
}
148+
149+
message GetHistoricalFeaturesResponse {
150+
// Export Job with ID assigned by Feast
151+
string id = 1;
152+
}
153+
154+
message StartStreamToOnlineIngestionJobRequest {
155+
// Feature table to ingest
156+
string project = 1;
157+
string table_name = 2;
158+
}
159+
160+
message StartStreamToOnlineIngestionJobResponse {
161+
// Job ID assigned by Feast
162+
string id = 1;
163+
}
164+
165+
message ListJobsRequest {
166+
Filter filter = 1;
167+
message Filter {
168+
// Filter jobs by job type
169+
JobType type = 1;
170+
// Filter jobs by current job status
171+
JobStatus status = 2;
172+
}
173+
}
174+
175+
message ListJobsResponse {
176+
repeated Job jobs = 1;
177+
}
178+
179+
message GetJobRequest {
180+
string job_id = 1;
181+
}
182+
183+
message GetJobResponse {
184+
Job job = 1;
185+
}
186+
187+
message RestartJobRequest {
188+
string job_id = 1;
189+
}
190+
191+
message RestartJobResponse {}
192+
193+
message StopJobRequest{
194+
string job_id = 1;
195+
}
196+
197+
message StopJobResponse {}

protos/feast/serving/ServingService.proto

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ message FeatureReference {
8484
message FeatureReferenceV2 {
8585
// Name of the Feature Table to retrieve the feature from.
8686
string feature_table = 1;
87-
87+
8888
// Name of the Feature to retrieve the feature from.
8989
string name = 2;
9090
}
@@ -120,27 +120,26 @@ message GetOnlineFeaturesRequest {
120120
message GetOnlineFeaturesRequestV2 {
121121
// List of features that are being retrieved
122122
repeated FeatureReferenceV2 features = 4;
123-
123+
124124
// List of entity rows, containing entity id and timestamp data.
125125
// Used during retrieval of feature rows and for joining feature
126126
// rows into a final dataset
127127
repeated EntityRow entity_rows = 2;
128-
128+
129129
// Optional field to specify project name override. If specified, uses the
130130
// given project for retrieval. Overrides the projects specified in
131131
// Feature References if both are specified.
132132
string project = 5;
133-
133+
134134
message EntityRow {
135-
// Request timestamp of this row. This value will be used,
136-
// together with maxAge, to determine feature staleness.
137-
google.protobuf.Timestamp timestamp = 1;
138-
139-
// Map containing mapping of entity name to entity value.
140-
map<string,feast.types.Value> fields = 2;
135+
// Request timestamp of this row. This value will be used,
136+
// together with maxAge, to determine feature staleness.
137+
google.protobuf.Timestamp timestamp = 1;
138+
139+
// Map containing mapping of entity name to entity value.
140+
map<string,feast.types.Value> fields = 2;
141141
}
142-
}
143-
142+
}
144143

145144
message GetBatchFeaturesRequest {
146145
// List of features that are being retrieved

sdk/go/go.mod

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ require (
77
github.com/golang/protobuf v1.4.2
88
github.com/google/go-cmp v0.5.1
99
github.com/opentracing/opentracing-go v1.1.0
10-
github.com/stretchr/testify v1.4.0 // indirect
1110
go.opencensus.io v0.22.4
1211
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
1312
google.golang.org/api v0.30.0

sdk/python/feast/cli.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,15 @@
2626
from feast.constants import CONFIG_SPARK_LAUNCHER
2727
from feast.entity import Entity
2828
from feast.feature_table import FeatureTable
29+
from feast.job_service import start_job_service
2930
from feast.loaders.yaml import yaml_loader
3031

3132
_logger = logging.getLogger(__name__)
3233

3334
_common_options = [
3435
click.option("--core-url", help="Set Feast core URL to connect to"),
3536
click.option("--serving-url", help="Set Feast serving URL to connect to"),
37+
click.option("--job-service-url", help="Set Feast job service URL to connect to"),
3638
]
3739

3840

@@ -491,5 +493,13 @@ def get_historical_features(features: str, entity_df_path: str, destination: str
491493
print(job.get_output_file_uri())
492494

493495

496+
@cli.command(name="server")
497+
def server():
498+
"""
499+
Start Feast Job Service
500+
"""
501+
start_job_service()
502+
503+
494504
if __name__ == "__main__":
495505
cli()

0 commit comments

Comments
 (0)