15
15
class BigSegmentStoreStatusProviderImpl (BigSegmentStoreStatusProvider ):
16
16
"""
17
17
Default implementation of the BigSegmentStoreStatusProvider interface.
18
-
18
+
19
19
The real implementation of getting the status is in BigSegmentStoreManager - we pass in a lambda that
20
20
allows us to get the current status from that class. So this class provides a facade for that, and
21
21
also adds the listener mechanism.
22
22
"""
23
+
23
24
def __init__ (self , status_getter : Callable [[], BigSegmentStoreStatus ]):
24
25
self .__status_getter = status_getter
25
26
self .__status_listeners = Listeners ()
26
27
self .__last_status = None # type: Optional[BigSegmentStoreStatus]
27
-
28
+
28
29
@property
29
30
def status (self ) -> BigSegmentStoreStatus :
30
31
return self .__status_getter ()
@@ -43,15 +44,17 @@ def _update_status(self, new_status: BigSegmentStoreStatus):
43
44
self .__last_status = new_status
44
45
self .__status_listeners .notify (new_status )
45
46
47
+
46
48
class BigSegmentStoreManager :
47
49
# use EMPTY_MEMBERSHIP as a singleton whenever a membership query returns None; it's safe to reuse it
48
50
# because we will never modify the membership properties after they're queried
49
51
EMPTY_MEMBERSHIP = {} # type: dict
50
-
52
+
51
53
"""
52
54
Internal component that decorates the Big Segment store with caching behavior, and also polls the
53
55
store to track its status.
54
56
"""
57
+
55
58
def __init__ (self , config : BigSegmentsConfig ):
56
59
self .__store = config .store
57
60
@@ -61,8 +64,8 @@ def __init__(self, config: BigSegmentsConfig):
61
64
self .__poll_task = None # type: Optional[RepeatingTask]
62
65
63
66
if self .__store :
64
- self .__cache = ExpiringDict (max_len = config .context_cache_size , max_age_seconds = config .context_cache_time )
65
- self .__poll_task = RepeatingTask (config .status_poll_interval , 0 , self .poll_store_and_update_status )
67
+ self .__cache = ExpiringDict (max_len = config .context_cache_size , max_age_seconds = config .context_cache_time )
68
+ self .__poll_task = RepeatingTask ("ldclient.bigsegment.status-poll" , config .status_poll_interval , 0 , self .poll_store_and_update_status )
66
69
self .__poll_task .start ()
67
70
68
71
def stop (self ):
@@ -74,7 +77,7 @@ def stop(self):
74
77
@property
75
78
def status_provider (self ) -> BigSegmentStoreStatusProvider :
76
79
return self .__status_provider
77
-
80
+
78
81
def get_user_membership (self , user_key : str ) -> Tuple [Optional [dict ], str ]:
79
82
if not self .__store :
80
83
return (None , BigSegmentsStatus .NOT_CONFIGURED )
@@ -101,7 +104,7 @@ def get_status(self) -> BigSegmentStoreStatus:
101
104
return status if status else self .poll_store_and_update_status ()
102
105
103
106
def poll_store_and_update_status (self ) -> BigSegmentStoreStatus :
104
- new_status = BigSegmentStoreStatus (False , False ) # default to "unavailable" if we don't get a new status below
107
+ new_status = BigSegmentStoreStatus (False , False ) # default to "unavailable" if we don't get a new status below
105
108
if self .__store :
106
109
try :
107
110
metadata = self .__store .get_metadata ()
@@ -115,5 +118,6 @@ def poll_store_and_update_status(self) -> BigSegmentStoreStatus:
115
118
def is_stale (self , timestamp ) -> bool :
116
119
return (timestamp is None ) or ((int (time .time () * 1000 ) - timestamp ) >= self .__stale_after_millis )
117
120
121
+
118
122
def _hash_for_user_key (user_key : str ) -> str :
119
123
return base64 .b64encode (sha256 (user_key .encode ('utf-8' )).digest ()).decode ('utf-8' )
0 commit comments