1
1
import json
2
+ import threading
3
+ from typing import Callable , Optional
2
4
3
5
import pkg_resources
4
6
import uvicorn
9
11
import feast
10
12
11
13
12
- def get_app (store : "feast.FeatureStore" , registry_dump : str , project_id : str ):
14
+ def get_app (
15
+ store : "feast.FeatureStore" ,
16
+ get_registry_dump : Callable ,
17
+ project_id : str ,
18
+ registry_ttl_secs : int ,
19
+ ):
13
20
ui_dir = pkg_resources .resource_filename (__name__ , "ui/build/" )
14
21
15
22
app = FastAPI ()
@@ -22,9 +29,33 @@ def get_app(store: "feast.FeatureStore", registry_dump: str, project_id: str):
22
29
allow_headers = ["*" ],
23
30
)
24
31
32
+ # Asynchronously refresh registry, notifying shutdown and canceling the active timer if the app is shutting down
33
+ registry_json = ""
34
+ shutting_down = False
35
+ active_timer : Optional [threading .Timer ] = None
36
+
37
+ def async_refresh ():
38
+ store .refresh_registry ()
39
+ nonlocal registry_json
40
+ registry_json = get_registry_dump (store .config , store .repo_path )
41
+ if shutting_down :
42
+ return
43
+ nonlocal active_timer
44
+ active_timer = threading .Timer (registry_ttl_secs , async_refresh )
45
+ active_timer .start ()
46
+
47
+ @app .on_event ("shutdown" )
48
+ def shutdown_event ():
49
+ nonlocal shutting_down
50
+ shutting_down = True
51
+ if active_timer :
52
+ active_timer .cancel ()
53
+
54
+ async_refresh ()
55
+
25
56
@app .get ("/registry" )
26
57
def read_registry ():
27
- return json .loads (registry_dump )
58
+ return json .loads (registry_json )
28
59
29
60
# Generate projects-list json that points to the current repo's project
30
61
# TODO(adchia): Enable users to also add project name + description fields in feature_store.yaml
@@ -59,6 +90,13 @@ def catch_all():
59
90
return app
60
91
61
92
62
- def start_server (store : "feast.FeatureStore" , registry_dump : str , project_id : str ):
63
- app = get_app (store , registry_dump , project_id )
64
- uvicorn .run (app , host = "0.0.0.0" , port = 8888 )
93
+ def start_server (
94
+ store : "feast.FeatureStore" ,
95
+ host : str ,
96
+ port : int ,
97
+ get_registry_dump : Callable ,
98
+ project_id : str ,
99
+ registry_ttl_sec : int ,
100
+ ):
101
+ app = get_app (store , get_registry_dump , project_id , registry_ttl_sec )
102
+ uvicorn .run (app , host = host , port = port )
0 commit comments