Пример #1
0
 internal DataSourceImpl(TestData parent, IDataSourceUpdateSink updateSink, User user, Logger log)
 {
     _parent     = parent;
     _updateSink = updateSink;
     User        = user;
     _log        = log;
 }
Пример #2
0
 public IDataSourceFactory AsFactory() =>
 new MockDataSourceFactoryFromLambda((ctx, updates, user, bg) =>
 {
     this._updateSink = updates;
     this._user       = user;
     return(this);
 });
 public IDataSource CreateDataSource(
     LdClientContext context,
     IDataSourceUpdateSink updateSink,
     User currentUser,
     bool inBackground
     ) =>
 new NullDataSource();
Пример #4
0
        /// <inheritdoc/>
        public IDataSource CreateDataSource(
            LdClientContext context,
            IDataSourceUpdateSink updateSink,
            User currentUser,
            bool inBackground
            )
        {
            var baseUri = StandardEndpoints.SelectBaseUri(
                context.ServiceEndpoints,
                e => e.StreamingBaseUri,
                "Streaming",
                context.BaseLogger
                );
            var pollingBaseUri = StandardEndpoints.SelectBaseUri(
                context.ServiceEndpoints,
                e => e.PollingBaseUri,
                "Polling",
                context.BaseLogger
                );

            if (inBackground)
            {
                // When in the background, always use polling instead of streaming
                return(new PollingDataSourceBuilder()
                       .BackgroundPollInterval(_backgroundPollInterval)
                       .CreateDataSource(context, updateSink, currentUser, true));
            }

            var logger    = context.BaseLogger.SubLogger(LogNames.DataSourceSubLog);
            var requestor = new FeatureFlagRequestor(
                pollingBaseUri,
                currentUser,
                context.EvaluationReasons,
                context.Http,
                logger
                );

            return(new StreamingDataSource(
                       updateSink,
                       currentUser,
                       baseUri,
                       context.EvaluationReasons,
                       _initialReconnectDelay,
                       requestor,
                       context.Http,
                       logger,
                       context.DiagnosticStore
                       ));
        }
Пример #5
0
 internal PollingDataSource(
     IDataSourceUpdateSink updateSink,
     User user,
     IFeatureFlagRequestor featureFlagRequestor,
     TimeSpan pollingInterval,
     TimeSpan initialDelay,
     TaskExecutor taskExecutor,
     Logger log)
 {
     this._featureFlagRequestor = featureFlagRequestor;
     this._updateSink           = updateSink;
     this._user            = user;
     this._pollingInterval = pollingInterval;
     this._initialDelay    = initialDelay;
     this._taskExecutor    = taskExecutor;
     this._log             = log;
     _startTask            = new TaskCompletionSource <bool>();
 }
Пример #6
0
        /// <inheritdoc/>
        public IDataSource CreateDataSource(
            LdClientContext context,
            IDataSourceUpdateSink updateSink,
            User currentUser,
            bool inBackground
            )
        {
            var instance = new DataSourceImpl(
                this,
                updateSink,
                currentUser,
                context.BaseLogger.SubLogger("DataSource.TestData")
                );

            lock (_lock)
            {
                _instances.Add(instance);
            }
            return(instance);
        }
Пример #7
0
 internal ConnectionManager(
     LdClientContext clientContext,
     IDataSourceFactory dataSourceFactory,
     IDataSourceUpdateSink updateSink,
     IEventProcessor eventProcessor,
     DiagnosticDisablerImpl diagnosticDisabler,
     bool enableBackgroundUpdating,
     User initialUser,
     Logger log
     )
 {
     _clientContext            = clientContext;
     _dataSourceFactory        = dataSourceFactory;
     _updateSink               = updateSink;
     _eventProcessor           = eventProcessor;
     _diagnosticDisabler       = diagnosticDisabler;
     _enableBackgroundUpdating = enableBackgroundUpdating;
     _user = initialUser;
     _log  = log;
 }
Пример #8
0
        /// <inheritdoc/>
        public IDataSource CreateDataSource(
            LdClientContext context,
            IDataSourceUpdateSink updateSink,
            User currentUser,
            bool inBackground
            )
        {
            if (!inBackground)
            {
                context.BaseLogger.Warn("You should only disable the streaming API if instructed to do so by LaunchDarkly support");
            }
            var baseUri = StandardEndpoints.SelectBaseUri(
                context.ServiceEndpoints,
                e => e.PollingBaseUri,
                "Polling",
                context.BaseLogger
                );

            var logger    = context.BaseLogger.SubLogger(LogNames.DataSourceSubLog);
            var requestor = new FeatureFlagRequestor(
                baseUri,
                currentUser,
                context.EvaluationReasons,
                context.Http,
                logger
                );

            return(new PollingDataSource(
                       updateSink,
                       currentUser,
                       requestor,
                       _pollInterval,
                       TimeSpan.Zero,
                       context.TaskExecutor,
                       logger
                       ));
        }
Пример #9
0
        internal DateTime _esStarted; // exposed for testing

        internal StreamingDataSource(
            IDataSourceUpdateSink updateSink,
            User user,
            Uri baseUri,
            bool withReasons,
            TimeSpan initialReconnectDelay,
            IFeatureFlagRequestor requestor,
            HttpConfiguration httpConfig,
            Logger log,
            IDiagnosticStore diagnosticStore
            )
        {
            this._updateSink            = updateSink;
            this._user                  = user;
            this._baseUri               = baseUri;
            this._useReport             = httpConfig.UseReport;
            this._withReasons           = withReasons;
            this._initialReconnectDelay = initialReconnectDelay;
            this._requestor             = requestor;
            this._httpProperties        = httpConfig.HttpProperties;
            this._diagnosticStore       = diagnosticStore;
            this._initTask              = new TaskCompletionSource <bool>();
            this._log = log;
        }
Пример #10
0
 private MockPollingProcessor(IDataSourceUpdateSink updateSink, User user, FullDataSet?data)
 {
     _updateSink = updateSink;
     _user       = user;
     _data       = data;
 }
Пример #11
0
 public IDataSource CreateDataSource(LdClientContext context, IDataSourceUpdateSink updateSink, User currentUser, bool inBackground) =>
 _fn(context, updateSink, currentUser, inBackground);
Пример #12
0
 public IDataSource CreateDataSource(LdClientContext context, IDataSourceUpdateSink updateSink, User currentUser, bool inBackground)
 {
     UpdateSink = updateSink;
     return(new MockDataSourceThatNeverInitializes());
 }
Пример #13
0
        LdClient(Configuration configuration, User user, TimeSpan startWaitTime)
        {
            if (user == null)
            {
                throw new ArgumentNullException(nameof(user));
            }

            _config = configuration ?? throw new ArgumentNullException(nameof(configuration));
            var diagnosticStore = _config.DiagnosticOptOut ? null :
                                  new ClientDiagnosticStore(_config, startWaitTime);
            var diagnosticDisabler = _config.DiagnosticOptOut ? null :
                                     new DiagnosticDisablerImpl();

            _context      = new LdClientContext(configuration, this, diagnosticStore, diagnosticDisabler);
            _log          = _context.BaseLogger;
            _taskExecutor = _context.TaskExecutor;
            diagnosticStore?.SetContext(_context);

            _log.Info("Starting LaunchDarkly Client {0}", Version);

            var persistenceConfiguration = (configuration.PersistenceConfigurationBuilder ?? Components.Persistence())
                                           .CreatePersistenceConfiguration(_context);

            _dataStore = new FlagDataManager(
                configuration.MobileKey,
                persistenceConfiguration,
                _log.SubLogger(LogNames.DataStoreSubLog)
                );

            _userDecorator = new UserDecorator(configuration.DeviceInfo ?? new DefaultDeviceInfo(),
                                               _dataStore.PersistentStore);
            _user = _userDecorator.DecorateUser(user);

            // If we had cached data for the new user, set the current in-memory flag data state to use
            // that data, so that any Variation calls made before Identify has completed will use the
            // last known values.
            var cachedData = _dataStore.GetCachedData(_user);

            if (cachedData != null)
            {
                _log.Debug("Cached flag data is available for this user");
                _dataStore.Init(_user, cachedData.Value, false); // false means "don't rewrite the flags to persistent storage"
            }

            var dataSourceUpdateSink = new DataSourceUpdateSinkImpl(
                _dataStore,
                configuration.Offline,
                _taskExecutor,
                _log.SubLogger(LogNames.DataSourceSubLog)
                );

            _dataSourceUpdateSink = dataSourceUpdateSink;

            _dataSourceStatusProvider = new DataSourceStatusProviderImpl(dataSourceUpdateSink);
            _flagTracker = new FlagTrackerImpl(dataSourceUpdateSink);

            var dataSourceFactory = configuration.DataSourceFactory ?? Components.StreamingDataSource();

            _connectivityStateManager = Factory.CreateConnectivityStateManager(configuration);
            var isConnected = _connectivityStateManager.IsConnected;

            diagnosticDisabler?.SetDisabled(!isConnected || configuration.Offline);

            _eventProcessor = (configuration.EventProcessorFactory ?? Components.SendEvents())
                              .CreateEventProcessor(_context);
            _eventProcessor.SetOffline(configuration.Offline || !isConnected);

            _connectionManager = new ConnectionManager(
                _context,
                dataSourceFactory,
                _dataSourceUpdateSink,
                _eventProcessor,
                diagnosticDisabler,
                configuration.EnableBackgroundUpdating,
                _user,
                _log
                );
            _connectionManager.SetForceOffline(configuration.Offline);
            _connectionManager.SetNetworkEnabled(isConnected);
            if (configuration.Offline)
            {
                _log.Info("Starting LaunchDarkly client in offline mode");
            }

            _connectivityStateManager.ConnectionChanged += networkAvailable =>
            {
                _log.Debug("Setting online to {0} due to a connectivity change event", networkAvailable);
                _ = _connectionManager.SetNetworkEnabled(networkAvailable);  // do not await the result
            };

            // Send an initial identify event, but only if we weren't explicitly set to be offline

            if (!configuration.Offline)
            {
                _eventProcessor.RecordIdentifyEvent(new EventProcessorTypes.IdentifyEvent
                {
                    Timestamp = UnixMillisecondTime.Now,
                    User      = user
                });
            }

            _backgroundModeManager = _config.BackgroundModeManager ?? new DefaultBackgroundModeManager();
            _backgroundModeManager.BackgroundModeChanged += OnBackgroundModeChanged;
        }