Skip to content

Commit 9583ed6

Browse files
fix: Add async refresh to prevent synchronous refresh in main thread (feast-dev#3812)
fix: Add async refresh to prevent synchronous refresh in main thread for http feature server Signed-off-by: Hai Nguyen <quanghai.ng1512@gmail.com>
1 parent 01db8cc commit 9583ed6

File tree

3 files changed

+43
-2
lines changed

3 files changed

+43
-2
lines changed

sdk/python/feast/cli.py

+10
Original file line numberDiff line numberDiff line change
@@ -663,6 +663,14 @@ def init_command(project_directory, minimal: bool, template: str):
663663
show_default=True,
664664
help="Timeout for keep alive",
665665
)
666+
@click.option(
667+
"--registry_ttl_sec",
668+
"-r",
669+
help="Number of seconds after which the registry is refreshed",
670+
type=click.INT,
671+
default=5,
672+
show_default=True,
673+
)
666674
@click.pass_context
667675
def serve_command(
668676
ctx: click.Context,
@@ -673,6 +681,7 @@ def serve_command(
673681
no_feature_log: bool,
674682
workers: int,
675683
keep_alive_timeout: int,
684+
registry_ttl_sec: int = 5,
676685
):
677686
"""Start a feature server locally on a given port."""
678687
store = create_feature_store(ctx)
@@ -685,6 +694,7 @@ def serve_command(
685694
no_feature_log=no_feature_log,
686695
workers=workers,
687696
keep_alive_timeout=keep_alive_timeout,
697+
registry_ttl_sec=registry_ttl_sec,
688698
)
689699

690700

sdk/python/feast/feature_server.py

+31-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import json
2+
import threading
23
import traceback
34
import warnings
45
from typing import List, Optional
@@ -44,14 +45,37 @@ class MaterializeIncrementalRequest(BaseModel):
4445
feature_views: Optional[List[str]] = None
4546

4647

47-
def get_app(store: "feast.FeatureStore"):
48+
def get_app(store: "feast.FeatureStore", registry_ttl_sec: int = 5):
4849
proto_json.patch()
4950

5051
app = FastAPI()
52+
# Asynchronously refresh registry, notifying shutdown and canceling the active timer if the app is shutting down
53+
registry_proto = None
54+
shutting_down = False
55+
active_timer: Optional[threading.Timer] = None
5156

5257
async def get_body(request: Request):
5358
return await request.body()
5459

60+
def async_refresh():
61+
store.refresh_registry()
62+
nonlocal registry_proto
63+
registry_proto = store.registry.proto()
64+
if shutting_down:
65+
return
66+
nonlocal active_timer
67+
active_timer = threading.Timer(registry_ttl_sec, async_refresh)
68+
active_timer.start()
69+
70+
@app.on_event("shutdown")
71+
def shutdown_event():
72+
nonlocal shutting_down
73+
shutting_down = True
74+
if active_timer:
75+
active_timer.cancel()
76+
77+
async_refresh()
78+
5579
@app.post("/get-online-features")
5680
def get_online_features(body=Depends(get_body)):
5781
try:
@@ -180,7 +204,10 @@ def materialize_incremental(body=Depends(get_body)):
180204

181205
class FeastServeApplication(gunicorn.app.base.BaseApplication):
182206
def __init__(self, store: "feast.FeatureStore", **options):
183-
self._app = get_app(store=store)
207+
self._app = get_app(
208+
store=store,
209+
registry_ttl_sec=options.get("registry_ttl_sec", 5),
210+
)
184211
self._options = options
185212
super().__init__()
186213

@@ -202,11 +229,13 @@ def start_server(
202229
no_access_log: bool,
203230
workers: int,
204231
keep_alive_timeout: int,
232+
registry_ttl_sec: int = 5,
205233
):
206234
FeastServeApplication(
207235
store=store,
208236
bind=f"{host}:{port}",
209237
accesslog=None if no_access_log else "-",
210238
workers=workers,
211239
keepalive=keep_alive_timeout,
240+
registry_ttl_sec=registry_ttl_sec,
212241
).run()

sdk/python/feast/feature_store.py

+2
Original file line numberDiff line numberDiff line change
@@ -2228,6 +2228,7 @@ def serve(
22282228
no_feature_log: bool,
22292229
workers: int,
22302230
keep_alive_timeout: int,
2231+
registry_ttl_sec: int,
22312232
) -> None:
22322233
"""Start the feature consumption server locally on a given port."""
22332234
type_ = type_.lower()
@@ -2243,6 +2244,7 @@ def serve(
22432244
no_access_log=no_access_log,
22442245
workers=workers,
22452246
keep_alive_timeout=keep_alive_timeout,
2247+
registry_ttl_sec=registry_ttl_sec,
22462248
)
22472249

22482250
@log_exceptions_and_usage

0 commit comments

Comments
 (0)