Exemplo n.º 1
0
    def run(self):
        if not self._running:
            log.info("Starting PollingUpdateProcessor with request interval: " + str(self._config.poll_interval))
            self._running = True
            while self._running:
                start_time = time.time()
                try:
                    all_data = self._requester.get_all_data()
                    self._store.init(all_data)
                    if not self._ready.is_set() is True and self._store.initialized is True:
                        log.info("PollingUpdateProcessor initialized ok")
                        self._ready.set()
                except HTTPError as e:
                    log.error('Received unexpected status code %d from polling request' % e.response.status_code)
                    if e.response.status_code == 401:
                        log.error('Received 401 error, no further polling requests will be made since SDK key is invalid')
                        self.stop()
                    break
                except:
                    log.exception(
                        'Error: Exception encountered when updating flags.')

                elapsed = time.time() - start_time
                if elapsed < self._config.poll_interval:
                    time.sleep(self._config.poll_interval - elapsed)
Exemplo n.º 2
0
 def _run_main_loop(self):
     log.info("Starting event processor")
     while True:
         try:
             message = self._inbox.get(block=True)
             if message.type == 'event':
                 self._process_event(message.param)
             elif message.type == 'flush':
                 self._trigger_flush()
             elif message.type == 'flush_users':
                 self._user_keys.clear()
             elif message.type == 'diagnostic':
                 self._send_and_reset_diagnostics()
             elif message.type == 'test_sync':
                 self._flush_workers.wait()
                 if self._diagnostic_accumulator is not None:
                     self._diagnostic_flush_workers.wait()
                 message.param.set()
             elif message.type == 'stop':
                 self._do_shutdown()
                 message.param.set()
                 return
         except Exception:
             log.error('Unhandled exception in event processor',
                       exc_info=True)
Exemplo n.º 3
0
 def run(self):
     log.info("Starting StreamingUpdateProcessor connecting to uri: " + self._uri)
     self._running = True
     while self._running:
         try:
             messages = self._connect()
             for msg in messages:
                 if not self._running:
                     break
                 message_ok = self.process_message(self._store, self._requester, msg)
                 if message_ok is True and self._ready.is_set() is False:
                     log.info("StreamingUpdateProcessor initialized ok.")
                     self._ready.set()
         except HTTPError as e:
             log.error("Received unexpected status code %d for stream connection" % e.response.status_code)
             if e.response.status_code == 401:
                 log.error("Received 401 error, no further streaming connection will be made since SDK key is invalid")
                 self.stop()
                 break
             else:
                 log.warning("Restarting stream connection after one second.")
         except Exception:
             log.warning("Caught exception. Restarting stream connection after one second.",
                         exc_info=True)
         time.sleep(1)
Exemplo n.º 4
0
 def process_message(store, requester, msg, ready):
     payload = json.loads(msg.data)
     log.debug("Received stream event {}".format(msg.event))
     if msg.event == 'put':
         store.init(payload)
         if not ready.is_set() and store.initialized:
             ready.set()
             log.info("StreamingUpdateProcessor initialized ok")
     elif msg.event == 'patch':
         key = payload['path'][1:]
         feature = payload['data']
         log.debug("Updating feature {}".format(key))
         store.upsert(key, feature)
     elif msg.event == "indirect/patch":
         key = payload['data']
         store.upsert(key, requester.get_one(key))
     elif msg.event == "indirect/put":
         store.init(requester.get_all())
         if not ready.is_set() and store.initialized:
             ready.set()
             log.info("StreamingUpdateProcessor initialized ok")
     elif msg.event == 'delete':
         key = payload['path'][1:]
         # noinspection PyShadowingNames
         version = payload['version']
         store.delete(key, version)
     else:
         log.warning('Unhandled event in stream processor: ' + msg.event)
Exemplo n.º 5
0
 def run(self):
     log.info("Starting MobileStreamingUpdateProcessor connecting to uri: " + self._uri)
     self._running = True
     while self._running:
         try:
             init_start = time.time()
             messages = self._connect()
             for msg in messages:
                 if not self._running:
                     break
                 message_ok = self.process_message(self._store, self._requester, msg)
                 if message_ok is True and self._ready.is_set() is False:
                     log.info("MobileStreamingUpdateProcessor initialized ok.")
                     init_duration = int((time.time() - init_start) * 1000)
                     request_success.fire(request_type="ld:init", name="mobile", response_time=init_duration, response_length=0)
                     self._ready.set()
         except UnsuccessfulResponseException as e:
             log.error(http_error_message(e.status, "stream connection"))
             init_duration = int((time.time() - init_start) * 1000)
             request_failure.fire(request_type="ld:init", name="mobile", response_time=init_duration, response_length=0, exception=e)
             if not is_http_error_recoverable(e.status):
                 self._ready.set()  # if client is initializing, make it stop waiting; has no effect if already inited
                 self.stop()
                 break
         except Exception as e:
             init_duration = int((time.time() - init_start) * 1000)
             request_failure.fire(request_type="ld:init", name="mobile", response_time=init_duration, response_length=0, exception=e)
             log.warning("Caught exception. Restarting stream connection after one second. %s" % e)
             # no stacktrace here because, for a typical connection error, it'll just be a lengthy tour of urllib3 internals
         time.sleep(1)
Exemplo n.º 6
0
    def _make_update_processor(self, config, store, ready,
                               diagnostic_accumulator):
        if config.update_processor_class:
            log.info("Using user-specified update processor: " +
                     str(config.update_processor_class))
            return config.update_processor_class(config, store, ready)

        if config.offline or config.use_ldd:
            return NullUpdateProcessor(config, store, ready)

        if config.feature_requester_class:
            feature_requester = config.feature_requester_class(config)
        else:
            feature_requester = FeatureRequesterImpl(config)
        """ :type: FeatureRequester """

        if config.stream:
            return StreamingUpdateProcessor(config, feature_requester, store,
                                            ready, diagnostic_accumulator)

        log.info("Disabling streaming API")
        log.warning(
            "You should only disable the streaming API if instructed to do so by LaunchDarkly support"
        )
        return PollingUpdateProcessor(config, feature_requester, store, ready)
Exemplo n.º 7
0
    def run(self):
        if not self._running:
            log.info("Starting PollingUpdateProcessor with request interval: " + str(self._config.poll_interval))
            self._running = True
            while self._running:
                start_time = time.time()
                try:
                    all_data = self._requester.get_all_data()
                    self._store.init(all_data)
                    if not self._ready.is_set() is True and self._store.initialized is True:
                        log.info("PollingUpdateProcessor initialized ok")
                        self._ready.set()
                except UnsuccessfulResponseException as e:
                    log.error(http_error_message(e.status, "polling request"))
                    if not is_http_error_recoverable(e.status):
                        self._ready.set() # if client is initializing, make it stop waiting; has no effect if already inited
                        self.stop()
                    break
                except Exception as e:
                    log.exception(
                        'Error: Exception encountered when updating flags. %s' % e)

                elapsed = time.time() - start_time
                if elapsed < self._config.poll_interval:
                    time.sleep(self._config.poll_interval - elapsed)
Exemplo n.º 8
0
 def run(self):
     log.info("Starting event consumer")
     self._running = True
     while self._running:
         try:
             self.send()
         except Exception:
             log.warning('Unhandled exception in event consumer')
Exemplo n.º 9
0
 def close(self):
     log.info("Closing LaunchDarkly client..")
     if self.is_offline():
         return
     if self._event_consumer and self._event_consumer.is_alive():
         self._event_consumer.stop()
     if self._update_processor and self._update_processor.is_alive():
         self._update_processor.stop()
Exemplo n.º 10
0
 def close(self):
     """Releases all threads and network connections used by the LaunchDarkly client.
     
     Do not attempt to use the client after calling this method.
     """
     log.info("Closing LaunchDarkly client..")
     self._event_processor.stop()
     self._update_processor.stop()
Exemplo n.º 11
0
    def __init__(self, sdk_key, config=None, start_wait=5):
        check_uwsgi()
        self._sdk_key = sdk_key
        self._config = config or Config.default()
        self._session = CacheControl(requests.Session())
        self._queue = queue.Queue(self._config.events_max_pending)
        self._event_consumer = None
        self._lock = Lock()

        self._store = self._config.feature_store
        """ :type: FeatureStore """

        if self._config.offline:
            self._config.events_enabled = False
            log.info("Started LaunchDarkly Client in offline mode")
            return

        if self._config.events_enabled:
            self._event_consumer = self._config.event_consumer_class(
                self._queue, self._sdk_key, self._config)
            self._event_consumer.start()

        if self._config.use_ldd:
            if self._store.__class__ == "RedisFeatureStore":
                log.info("Started LaunchDarkly Client in LDD mode")
                return
            log.error("LDD mode requires a RedisFeatureStore.")
            return

        if self._config.feature_requester_class:
            self._feature_requester = self._config.feature_requester_class(
                sdk_key, self._config)
        else:
            self._feature_requester = FeatureRequesterImpl(sdk_key, self._config)
        """ :type: FeatureRequester """

        update_processor_ready = threading.Event()

        if self._config.update_processor_class:
            self._update_processor = self._config.update_processor_class(
                sdk_key, self._config, self._feature_requester, self._store, update_processor_ready)
        else:
            if self._config.stream:
                self._update_processor = StreamingUpdateProcessor(
                    sdk_key, self._config, self._feature_requester, self._store, update_processor_ready)
            else:
                self._update_processor = PollingUpdateProcessor(
                    sdk_key, self._config, self._feature_requester, self._store, update_processor_ready)
        """ :type: UpdateProcessor """

        self._update_processor.start()
        log.info("Waiting up to " + str(start_wait) + " seconds for LaunchDarkly client to initialize...")
        update_processor_ready.wait(start_wait)

        if self._update_processor.initialized:
            log.info("Started LaunchDarkly Client: OK")
        else:
            log.info("Initialization timeout exceeded for LaunchDarkly Client. Feature Flags may not yet be available.")
Exemplo n.º 12
0
 def run(self):
     if not self._running:
         log.info("Starting PollingUpdateProcessor with request interval: " + str(self._config.poll_interval))
         self._running = True
         while self._running:
             start_time = time.time()
             self._store.init(self._requester.get_all())
             if not self._ready.is_set() is True and self._store.initialized is True:
                 log.info("PollingUpdateProcessor initialized ok")
                 self._ready.set()
             elapsed = time.time() - start_time
             if elapsed < self._config.poll_interval:
                 time.sleep(self._config.poll_interval - elapsed)
Exemplo n.º 13
0
 def close(self):
     """Releases all threads and network connections used by the LaunchDarkly client.
     
     Do not attempt to use the client after calling this method.
     """
     log.info("Closing LaunchDarkly client..")
     if self.is_offline():
         return
     if self._event_processor:
         self._event_processor.stop()
     if self._config.use_ldd:
         return
     if self._update_processor and self._update_processor.is_alive():
         self._update_processor.stop()
 def __init__(self,
              url='redis://localhost:6379/0',
              expiration=15,
              capacity=1000,
              redis_prefix='launchdarkly'):
     self._url = url
     parsed_url = urlparse.urlparse(url)
     self._redis_host = parsed_url.hostname
     self._redis_port = parsed_url.port
     self._features_key = "{}:features".format(redis_prefix)
     self._cache = ForgetfulDict() if expiration == 0 else ExpiringDict(
         max_len=capacity, max_age_seconds=expiration)
     log.info("Created TwistedRedisFeatureStore with url: " + url +
              " using key: " + self._features_key)
Exemplo n.º 15
0
        def cb(flag):
            try:
                if not flag:
                    log.info("Feature Flag key: " + key +
                             " not found in Feature Store. Returning default.")
                    send_event(default)
                    return default

                return self._evaluate_and_send_events(flag, user, default)

            except Exception as e:
                log.error("Exception caught in variation: " + e.message +
                          " for flag key: " + key + " and user: " + str(user))

            return default
    def __init__(self, user, sdk_key=None, config=None, start_wait=5):
        """Constructs a new LDClient instance.
        :param string sdk_key: the SDK key for your LaunchDarkly environment
        :param ldclient.config.Config config: optional custom configuration
        :param float start_wait: the number of seconds to wait for a successful connection to LaunchDarkly
        """

        if user is None:
            raise Exception("user is required for mobile sdk")

        if config is not None and config.sdk_key is not None and sdk_key is not None:
            raise Exception(
                "LaunchDarkly client init received both sdk_key and config with sdk_key. "
                "Only one of either is expected")

        if sdk_key is not None:
            log.warning(
                "Deprecated sdk_key argument was passed to init. Use config object instead."
            )
            self._config = MobileConfig(sdk_key=sdk_key)
        else:
            self._config = config.copy_with_new_user(
                user) or MobileConfig.default().copy_with_new_user(user=user)

        self._config._validate()

        self._event_processor = None
        self._lock = Lock()
        self._event_factory_default = _EventFactory(False)
        self._event_factory_with_reasons = _EventFactory(True)

        self._store = _FeatureStoreClientWrapper(self._config.feature_store)
        """ :type: FeatureStore """

        if self._config.offline:
            log.info("Started LaunchDarkly Client in offline mode")

        if self._config.use_ldd:
            log.info("Started LaunchDarkly Client in LDD mode")

        self._event_processor = self._make_event_processor(self._config)
        update_processor_ready = threading.Event()
        self._update_processor = self._make_update_processor(
            self._config, self._store, update_processor_ready)
        self._update_processor.start()

        if start_wait > 0 and not self._config.offline and not self._config.use_ldd:
            log.info("Waiting up to " + str(start_wait) +
                     " seconds for LaunchDarkly client to initialize...")
            update_processor_ready.wait(start_wait)

        if self._update_processor.initialized() is True:
            log.info("Started LaunchDarkly Client: OK")

        else:
            log.warning(
                "Initialization timeout exceeded for LaunchDarkly Client or an error occurred. "
                "Feature Flags may not yet be available.")
Exemplo n.º 17
0
 def run(self):
     log.info("Starting StreamingUpdateProcessor connecting to uri: " + self._config.stream_uri)
     self._running = True
     hdrs = _stream_headers(self._sdk_key)
     uri = self._config.stream_uri
     while self._running:
         try:
             messages = SSEClient(uri, verify=self._config.verify_ssl, headers=hdrs)
             for msg in messages:
                 if not self._running:
                     break
                 self.process_message(self._store, self._requester, msg, self._ready)
         except Exception as e:
             log.error("Could not connect to LaunchDarkly stream: " + str(e.message) +
                       " waiting 1 second before trying again.")
             time.sleep(1)
Exemplo n.º 18
0
 def _run_main_loop(self):
     log.info("Starting event processor")
     while True:
         try:
             message = self._queue.get(block=True)
             if message.type == 'event':
                 self._process_event(message.param)
             elif message.type == 'flush':
                 self._trigger_flush()
             elif message.type == 'flush_users':
                 self._user_keys.clear()
             elif message.type == 'test_sync':
                 self._flush_workers.wait()
                 message.param.set()
             elif message.type == 'stop':
                 self._do_shutdown()
                 message.param.set()
                 return
         except Exception:
             log.error('Unhandled exception in event processor', exc_info=True)
Exemplo n.º 19
0
 def run(self):
     log.info("Starting StreamingUpdateProcessor connecting to uri: " + self._uri)
     self._running = True
     while self._running:
         try:
             messages = self._connect()
             for msg in messages:
                 if not self._running:
                     break
                 message_ok = self.process_message(self._store, self._requester, msg)
                 if message_ok is True and self._ready.is_set() is False:
                     log.info("StreamingUpdateProcessor initialized ok.")
                     self._ready.set()
         except UnsuccessfulResponseException as e:
             log.error(http_error_message(e.status, "stream connection"))
             if not is_http_error_recoverable(e.status):
                 self._ready.set()  # if client is initializing, make it stop waiting; has no effect if already inited
                 self.stop()
                 break
         except Exception as e:
             log.warning("Caught exception. Restarting stream connection after one second. %s" % e)
             # no stacktrace here because, for a typical connection error, it'll just be a lengthy tour of urllib3 internals
         time.sleep(1)
Exemplo n.º 20
0
 def run(self):
     log.info("Starting StreamingUpdateProcessor connecting to uri: " +
              self._uri)
     self._running = True
     while self._running:
         try:
             self._es_started = int(time.time() * 1000)
             messages = self._connect()
             for msg in messages:
                 if not self._running:
                     break
                 message_ok = self.process_message(self._store,
                                                   self._requester, msg)
                 if message_ok:
                     self._record_stream_init(False)
                     self._es_started = None
                 if message_ok is True and self._ready.is_set() is False:
                     log.info("StreamingUpdateProcessor initialized ok.")
                     self._ready.set()
         except UnsuccessfulResponseException as e:
             log.error(http_error_message(e.status, "stream connection"))
             self._record_stream_init(True)
             self._es_started = None
             if not is_http_error_recoverable(e.status):
                 self._ready.set(
                 )  # if client is initializing, make it stop waiting; has no effect if already inited
                 self.stop()
                 break
         except Exception as e:
             log.warning(
                 "Caught exception. Restarting stream connection after one second. %s"
                 % e)
             self._record_stream_init(True)
             self._es_started = None
             # no stacktrace here because, for a typical connection error, it'll just be a lengthy tour of urllib3 internals
         time.sleep(1)
Exemplo n.º 21
0
    def run(self):
        if not self._running:
            log.info("Starting PollingUpdateProcessor with request interval: " + str(self._config.poll_interval))
            self._running = True
            while self._running:
                start_time = time.time()
                try:
                    all_data = self._requester.get_all_data()
                    self._store.init(all_data)
                    if not self._ready.is_set() is True and self._store.initialized is True:
                        log.info("PollingUpdateProcessor initialized ok")
                        self._ready.set()
                except UnsuccessfulResponseException as e:
                    log.error(http_error_message(e.status, "polling request"))
                    if not is_http_error_recoverable(e.status):
                        self._ready.set() # if client is initializing, make it stop waiting; has no effect if already inited
                        self.stop()
                except Exception as e:
                    log.exception(
                        'Error: Exception encountered when updating flags. %s' % e)

                elapsed = time.time() - start_time
                if elapsed < self._config.poll_interval:
                    time.sleep(self._config.poll_interval - elapsed)
Exemplo n.º 22
0
    def __init__(self, config: Config, start_wait: float = 5):
        """Constructs a new LDClient instance.

        :param config: optional custom configuration
        :param start_wait: the number of seconds to wait for a successful connection to LaunchDarkly
        """
        check_uwsgi()

        self._config = config
        self._config._validate()

        self._event_processor = None
        self._lock = Lock()
        self._event_factory_default = _EventFactory(False)
        self._event_factory_with_reasons = _EventFactory(True)

        self._store = _FeatureStoreClientWrapper(self._config.feature_store)
        """ :type: FeatureStore """

        if self._config.offline:
            log.info("Started LaunchDarkly Client in offline mode")

        if self._config.use_ldd:
            log.info("Started LaunchDarkly Client in LDD mode")

        diagnostic_accumulator = self._set_event_processor(self._config)

        update_processor_ready = threading.Event()
        self._update_processor = self._make_update_processor(
            self._config, self._store, update_processor_ready,
            diagnostic_accumulator)
        self._update_processor.start()

        if start_wait > 0 and not self._config.offline and not self._config.use_ldd:
            log.info("Waiting up to " + str(start_wait) +
                     " seconds for LaunchDarkly client to initialize...")
            update_processor_ready.wait(start_wait)

        if self._update_processor.initialized() is True:
            log.info("Started LaunchDarkly Client: OK")
        else:
            log.warning(
                "Initialization timeout exceeded for LaunchDarkly Client or an error occurred. "
                "Feature Flags may not yet be available.")
Exemplo n.º 23
0
 def run(self):
     log.info("Starting StreamingUpdateProcessor connecting to uri: " +
              self._uri)
     self._running = True
     attempts = 0
     while self._running:
         if attempts > 0:
             delay = self._retry_delay.next_retry_delay(time.time())
             log.info("Will reconnect after delay of %fs" % delay)
             time.sleep(delay)
         attempts += 1
         try:
             self._es_started = int(time.time() * 1000)
             messages = self._connect()
             for msg in messages:
                 if not self._running:
                     break
                 self._retry_delay.set_good_since(time.time())
                 message_ok = self.process_message(self._store, msg)
                 if message_ok:
                     self._record_stream_init(False)
                     self._es_started = None
                 if message_ok is True and self._ready.is_set() is False:
                     log.info("StreamingUpdateProcessor initialized ok.")
                     self._ready.set()
         except UnsuccessfulResponseException as e:
             log.error(http_error_message(e.status, "stream connection"))
             self._record_stream_init(True)
             self._es_started = None
             if not is_http_error_recoverable(e.status):
                 self._ready.set(
                 )  # if client is initializing, make it stop waiting; has no effect if already inited
                 self.stop()
                 break
         except Exception as e:
             log.warning(
                 "Unexpected error on stream connection: %s, will retry" %
                 e)
             self._record_stream_init(True)
             self._es_started = None
Exemplo n.º 24
0
 def log_backoff_message(props):
     log.error("Streaming connection failed, will attempt to restart")
     log.info("Will reconnect after delay of %fs", props['wait'])
Exemplo n.º 25
0
 def stop(self):
     log.info("Stopping StreamingUpdateProcessor")
     self._running = False
Exemplo n.º 26
0
 def stop(self):
     log.info("Stopping StreamingUpdateProcessor")
     self._running = False
Exemplo n.º 27
0
 def run(self):
     log.info("Starting event consumer")
     self._running = True
     while self._running:
         self.send()
Exemplo n.º 28
0
    def __init__(self, sdk_key=None, config=None, start_wait=5):
        """Constructs a new LDClient instance.

        :param string sdk_key: the SDK key for your LaunchDarkly environment
        :param ldclient.config.Config config: optional custom configuration
        :param float start_wait: the number of seconds to wait for a successful connection to LaunchDarkly
        """
        check_uwsgi()

        if config is not None and config.sdk_key is not None and sdk_key is not None:
            raise Exception(
                "LaunchDarkly client init received both sdk_key and config with sdk_key. "
                "Only one of either is expected")

        if sdk_key is not None:
            log.warn(
                "Deprecated sdk_key argument was passed to init. Use config object instead."
            )
            self._config = Config(sdk_key=sdk_key)
        else:
            self._config = config or Config.default()
        self._config._validate()

        self._event_processor = None
        self._lock = Lock()

        self._store = _FeatureStoreClientWrapper(self._config.feature_store)
        """ :type: FeatureStore """

        if self._config.offline or not self._config.send_events:
            self._event_processor = NullEventProcessor()
        else:
            self._event_processor = self._config.event_processor_class(
                self._config)

        if self._config.offline:
            log.info("Started LaunchDarkly Client in offline mode")
            return

        if self._config.use_ldd:
            log.info("Started LaunchDarkly Client in LDD mode")
            return

        update_processor_ready = threading.Event()

        if self._config.update_processor_class:
            log.info("Using user-specified update processor: " +
                     str(self._config.update_processor_class))
            self._update_processor = self._config.update_processor_class(
                self._config, self._store, update_processor_ready)
        else:
            if self._config.feature_requester_class:
                feature_requester = self._config.feature_requester_class(
                    self._config)
            else:
                feature_requester = FeatureRequesterImpl(self._config)
            """ :type: FeatureRequester """

            if self._config.stream:
                self._update_processor = StreamingUpdateProcessor(
                    self._config, feature_requester, self._store,
                    update_processor_ready)
            else:
                log.info("Disabling streaming API")
                log.warn(
                    "You should only disable the streaming API if instructed to do so by LaunchDarkly support"
                )
                self._update_processor = PollingUpdateProcessor(
                    self._config, feature_requester, self._store,
                    update_processor_ready)
        """ :type: UpdateProcessor """

        self._update_processor.start()
        log.info("Waiting up to " + str(start_wait) +
                 " seconds for LaunchDarkly client to initialize...")
        update_processor_ready.wait(start_wait)

        if self._update_processor.initialized() is True:
            log.info("Started LaunchDarkly Client: OK")
        else:
            log.warn(
                "Initialization timeout exceeded for LaunchDarkly Client or an error occurred. "
                "Feature Flags may not yet be available.")
Exemplo n.º 29
0
 def log_backoff_message(props):
     log.error("Streaming connection failed, will attempt to restart")
     log.info("Will reconnect after delay of %fs", props['wait'])
Exemplo n.º 30
0
    def __init__(self, sdk_key=None, config=None, start_wait=5):
        check_uwsgi()

        if config is not None and config.sdk_key is not None and sdk_key is not None:
            raise Exception(
                "LaunchDarkly client init received both sdk_key and config with sdk_key. "
                "Only one of either is expected")

        if sdk_key is not None:
            log.warn(
                "Deprecated sdk_key argument was passed to init. Use config object instead."
            )
            self._config = Config(sdk_key=sdk_key)
        else:
            self._config = config or Config.default()
        self._config._validate()

        self._session = CacheControl(requests.Session())
        self._queue = queue.Queue(self._config.events_max_pending)
        self._event_consumer = None
        self._lock = Lock()

        self._store = self._config.feature_store
        """ :type: FeatureStore """

        if self._config.offline:
            log.info("Started LaunchDarkly Client in offline mode")
            return

        if self._config.events_enabled:
            self._event_consumer = self._config.event_consumer_class(
                self._queue, self._config)
            self._event_consumer.start()

        if self._config.use_ldd:
            log.info("Started LaunchDarkly Client in LDD mode")
            return

        if self._config.feature_requester_class:
            self._feature_requester = self._config.feature_requester_class(
                self._config)
        else:
            self._feature_requester = FeatureRequesterImpl(self._config)
        """ :type: FeatureRequester """

        update_processor_ready = threading.Event()

        if self._config.update_processor_class:
            log.info("Using user-specified update processor: " +
                     str(self._config.update_processor_class))
            self._update_processor = self._config.update_processor_class(
                self._config, self._feature_requester, self._store,
                update_processor_ready)
        else:
            if self._config.stream:
                self._update_processor = StreamingUpdateProcessor(
                    self._config, self._feature_requester, self._store,
                    update_processor_ready)
            else:
                self._update_processor = PollingUpdateProcessor(
                    self._config, self._feature_requester, self._store,
                    update_processor_ready)
        """ :type: UpdateProcessor """

        self._update_processor.start()
        log.info("Waiting up to " + str(start_wait) +
                 " seconds for LaunchDarkly client to initialize...")
        update_processor_ready.wait(start_wait)

        if self._update_processor.initialized() is True:
            log.info("Started LaunchDarkly Client: OK")
        else:
            log.warn(
                "Initialization timeout exceeded for LaunchDarkly Client or an error occurred. "
                "Feature Flags may not yet be available.")
Exemplo n.º 31
0
 def run(self):
     log.info("Starting StreamingUpdateProcessor connecting to uri: " + self._uri)
     self._running = True
     while self._running:
         self._connect()