8
8
import traceback
9
9
10
10
from ldclient .config import Config as Config
11
- from ldclient .event_processor import NullEventProcessor
12
11
from ldclient .feature_requester import FeatureRequesterImpl
13
12
from ldclient .feature_store import _FeatureStoreDataSetSorter
14
13
from ldclient .flag import EvaluationDetail , evaluate , error_reason
15
14
from ldclient .flags_state import FeatureFlagsState
15
+ from ldclient .impl .stubs import NullEventProcessor , NullUpdateProcessor
16
16
from ldclient .interfaces import FeatureStore
17
17
from ldclient .polling import PollingUpdateProcessor
18
18
from ldclient .streaming import StreamingUpdateProcessor
@@ -94,52 +94,54 @@ def __init__(self, sdk_key=None, config=None, start_wait=5):
94
94
self ._store = _FeatureStoreClientWrapper (self ._config .feature_store )
95
95
""" :type: FeatureStore """
96
96
97
- if self ._config .offline or not self ._config .send_events :
98
- self ._event_processor = NullEventProcessor ()
99
- else :
100
- self ._event_processor = self ._config .event_processor_class (self ._config )
101
-
102
97
if self ._config .offline :
103
98
log .info ("Started LaunchDarkly Client in offline mode" )
104
- return
105
99
106
100
if self ._config .use_ldd :
107
101
log .info ("Started LaunchDarkly Client in LDD mode" )
108
- return
109
102
110
- update_processor_ready = threading .Event ()
111
-
112
- if self ._config .update_processor_class :
113
- log .info ("Using user-specified update processor: " + str (self ._config .update_processor_class ))
114
- self ._update_processor = self ._config .update_processor_class (
115
- self ._config , self ._store , update_processor_ready )
116
- else :
117
- if self ._config .feature_requester_class :
118
- feature_requester = self ._config .feature_requester_class (self ._config )
119
- else :
120
- feature_requester = FeatureRequesterImpl (self ._config )
121
- """ :type: FeatureRequester """
122
-
123
- if self ._config .stream :
124
- self ._update_processor = StreamingUpdateProcessor (
125
- self ._config , feature_requester , self ._store , update_processor_ready )
126
- else :
127
- log .info ("Disabling streaming API" )
128
- log .warn ("You should only disable the streaming API if instructed to do so by LaunchDarkly support" )
129
- self ._update_processor = PollingUpdateProcessor (
130
- self ._config , feature_requester , self ._store , update_processor_ready )
131
- """ :type: UpdateProcessor """
103
+ self ._event_processor = self ._make_event_processor (self ._config )
132
104
105
+ update_processor_ready = threading .Event ()
106
+ self ._update_processor = self ._make_update_processor (self ._config , self ._store , update_processor_ready )
133
107
self ._update_processor .start ()
134
- log .info ("Waiting up to " + str (start_wait ) + " seconds for LaunchDarkly client to initialize..." )
135
- update_processor_ready .wait (start_wait )
108
+
109
+ if start_wait > 0 and not self ._config .offline and not self ._config .use_ldd :
110
+ log .info ("Waiting up to " + str (start_wait ) + " seconds for LaunchDarkly client to initialize..." )
111
+ update_processor_ready .wait (start_wait )
136
112
137
113
if self ._update_processor .initialized () is True :
138
114
log .info ("Started LaunchDarkly Client: OK" )
139
115
else :
140
116
log .warn ("Initialization timeout exceeded for LaunchDarkly Client or an error occurred. "
141
117
"Feature Flags may not yet be available." )
142
118
119
+ def _make_event_processor (self , config ):
120
+ if config .offline or not config .send_events :
121
+ return NullEventProcessor ()
122
+ return config .event_processor_class (config )
123
+
124
+ def _make_update_processor (self , config , store , ready ):
125
+ if config .update_processor_class :
126
+ log .info ("Using user-specified update processor: " + str (config .update_processor_class ))
127
+ return self ._config .update_processor_class (config , store , ready )
128
+
129
+ if config .offline or config .use_ldd :
130
+ return NullUpdateProcessor (config , store , ready )
131
+
132
+ if config .feature_requester_class :
133
+ feature_requester = config .feature_requester_class (config )
134
+ else :
135
+ feature_requester = FeatureRequesterImpl (config )
136
+ """ :type: FeatureRequester """
137
+
138
+ if config .stream :
139
+ return StreamingUpdateProcessor (config , feature_requester , store , ready )
140
+
141
+ log .info ("Disabling streaming API" )
142
+ log .warn ("You should only disable the streaming API if instructed to do so by LaunchDarkly support" )
143
+ return PollingUpdateProcessor (config , feature_requester , store , ready )
144
+
143
145
def get_sdk_key (self ):
144
146
"""Returns the configured SDK key.
145
147
@@ -153,13 +155,16 @@ def close(self):
153
155
Do not attempt to use the client after calling this method.
154
156
"""
155
157
log .info ("Closing LaunchDarkly client.." )
156
- if self .is_offline ():
157
- return
158
- if self ._event_processor :
159
- self ._event_processor .stop ()
160
- if self ._update_processor and self ._update_processor .is_alive ():
161
- self ._update_processor .stop ()
158
+ self ._event_processor .stop ()
159
+ self ._update_processor .stop ()
162
160
161
+ # These magic methods allow a client object to be automatically cleaned up by the "with" scope operator
162
+ def __enter__ (self ):
163
+ return self
164
+
165
+ def __exit__ (self , type , value , traceback ):
166
+ self .close ()
167
+
163
168
def _send_event (self , event ):
164
169
self ._event_processor .send_event (event )
165
170
0 commit comments