internal StreamProcessor( LdClientContext context, IDataSourceUpdates dataSourceUpdates, Uri baseUri, TimeSpan initialReconnectDelay, EventSourceCreator eventSourceCreator ) { _log = context.Basic.Logger.SubLogger(LogNames.DataSourceSubLog); _log.Info("Connecting to LaunchDarkly stream"); _dataSourceUpdates = dataSourceUpdates; _httpConfig = context.Http; _initialReconnectDelay = initialReconnectDelay; _diagnosticStore = context.DiagnosticStore; _initTask = new TaskCompletionSource <bool>(); _streamUri = new Uri(baseUri, "/all"); _storeStatusMonitoringEnabled = _dataSourceUpdates.DataStoreStatusProvider.StatusMonitoringEnabled; if (_storeStatusMonitoringEnabled) { _dataSourceUpdates.DataStoreStatusProvider.StatusChanged += OnDataStoreStatusChanged; } _es = (eventSourceCreator ?? CreateEventSource)(_streamUri, _httpConfig); _es.MessageReceived += OnMessage; _es.Error += OnError; _es.Opened += OnOpen; }
internal LdClientContext( Configuration configuration, object eventSender, IDiagnosticStore diagnosticStore, IDiagnosticDisabler diagnosticDisabler ) { this.Basic = new BasicConfiguration(configuration.MobileKey); var logConfig = (configuration.LoggingConfigurationBuilder ?? Components.Logging()) .CreateLoggingConfiguration(); var logAdapter = logConfig.LogAdapter ?? Logs.None; this.BaseLogger = logAdapter.Logger(logConfig.BaseLoggerName ?? LogNames.Base); this.EnableBackgroundUpdating = configuration.EnableBackgroundUpdating; this.EvaluationReasons = configuration.EvaluationReasons; this.Http = (configuration.HttpConfigurationBuilder ?? Components.HttpConfiguration()) .CreateHttpConfiguration(this.Basic); this.ServiceEndpoints = configuration.ServiceEndpoints; this.DiagnosticStore = diagnosticStore; this.DiagnosticDisabler = diagnosticDisabler; this.TaskExecutor = new TaskExecutor( eventSender, PlatformSpecific.AsyncScheduler.ScheduleAction, this.BaseLogger ); }
internal EventProcessorInternal( EventsConfiguration config, BlockingCollection <IEventMessage> messageQueue, IEventSender eventSender, IUserDeduplicator userDeduplicator, IDiagnosticStore diagnosticStore, Logger logger, Action testActionOnDiagnosticSend ) { _config = config; _diagnosticStore = diagnosticStore; _userDeduplicator = userDeduplicator; _testActionOnDiagnosticSend = testActionOnDiagnosticSend; _flushWorkersCounter = new CountdownEvent(1); _eventSender = eventSender; _logger = logger; _random = new Random(); EventBuffer buffer = new EventBuffer(config.EventCapacity > 0 ? config.EventCapacity : 1, _diagnosticStore, _logger); // Here we use TaskFactory.StartNew instead of Task.Run() because that allows us to specify the // LongRunning option. This option tells the task scheduler that the task is likely to hang on // to a thread for a long time, so it should consider growing the thread pool. Task.Factory.StartNew( () => RunMainLoop(messageQueue, buffer), TaskCreationOptions.LongRunning ); }
public void DiagnosticStorePassedToFactoriesWhenSupported() { var epfwd = new Mock <IEventProcessorFactoryWithDiagnostics>(); var upfwd = new Mock <IUpdateProcessorFactoryWithDiagnostics>(); var config = Configuration.Builder("SDK_KEY") .IsStreamingEnabled(false) .BaseUri(new Uri("http://fake")) .StartWaitTime(TimeSpan.Zero) .EventProcessorFactory(epfwd.Object) .UpdateProcessorFactory(upfwd.Object) .Build(); IDiagnosticStore eventProcessorDiagnosticStore = null; IDiagnosticStore updateProcessorDiagnosticStore = null; epfwd.Setup(epf => epf.CreateEventProcessor(config, It.IsAny <IDiagnosticStore>())) .Callback <Configuration, IDiagnosticStore>((c, ds) => eventProcessorDiagnosticStore = ds) .Returns(Components.NullEventProcessor.CreateEventProcessor(config)); upfwd.Setup(upf => upf.CreateUpdateProcessor(config, It.IsAny <IFeatureStore>(), It.IsAny <IDiagnosticStore>())) .Callback <Configuration, IFeatureStore, IDiagnosticStore>((c, fs, ds) => updateProcessorDiagnosticStore = ds) .Returns(updateProcessor); using (var client = new LdClient(config)) { epfwd.Verify(epf => epf.CreateEventProcessor(config, It.IsNotNull <IDiagnosticStore>()), Times.Once()); epfwd.VerifyNoOtherCalls(); upfwd.Verify(upf => upf.CreateUpdateProcessor(config, It.IsNotNull <IFeatureStore>(), It.IsNotNull <IDiagnosticStore>()), Times.Once()); upfwd.VerifyNoOtherCalls(); Assert.True(eventProcessorDiagnosticStore == updateProcessorDiagnosticStore); } }
public void PersistedEventIsNull() { IDiagnosticStore _serverDiagnosticStore = CreateDiagnosticStore(); var persistedEvent = _serverDiagnosticStore.PersistedUnsentEvent; Assert.Null(persistedEvent); }
public void DiagnosticStoreNotPassedToFactoriesWhenOptedOut() { var epf = new Mock <IEventProcessorFactory>(); var dsf = new Mock <IDataSourceFactory>(); var config = BasicConfig() .Events(epf.Object) .DataSource(dsf.Object) .DiagnosticOptOut(true) .Build(); IDiagnosticStore eventProcessorDiagnosticStore = null; IDiagnosticStore dataSourceDiagnosticStore = null; var dataSource = MockDataSourceWithStartFn(_ => Task.FromResult(true)); epf.Setup(f => f.CreateEventProcessor(It.IsAny <LdClientContext>())) .Callback((LdClientContext ctx) => eventProcessorDiagnosticStore = ctx.DiagnosticStore) .Returns(new ComponentsImpl.NullEventProcessor()); dsf.Setup(f => f.CreateDataSource(It.IsAny <LdClientContext>(), It.IsAny <IDataSourceUpdates>())) .Callback((LdClientContext ctx, IDataSourceUpdates dsu) => dataSourceDiagnosticStore = ctx.DiagnosticStore) .Returns((LdClientContext ctx, IDataSourceUpdates dsu) => dataSource); using (var client = new LdClient(config)) { epf.Verify(f => f.CreateEventProcessor(It.IsNotNull <LdClientContext>()), Times.Once()); epf.VerifyNoOtherCalls(); dsf.Verify(f => f.CreateDataSource(It.IsNotNull <LdClientContext>(), It.IsNotNull <IDataSourceUpdates>()), Times.Once()); dsf.VerifyNoOtherCalls(); Assert.Null(eventProcessorDiagnosticStore); Assert.Null(dataSourceDiagnosticStore); } }
public void DiagnosticStoreNotPassedToFactoriesWhenOptedOut() { var epf = new Mock <IEventProcessorFactory>(); var dsf = new Mock <IDataSourceFactory>(); var config = Configuration.Builder(sdkKey) .DataSource(Components.ExternalUpdatesOnly) .StartWaitTime(TimeSpan.Zero) .Events(epf.Object) .DataSource(dsf.Object) .DiagnosticOptOut(true) .Logging(Components.Logging(testLogging)) .Build(); IDiagnosticStore eventProcessorDiagnosticStore = null; IDiagnosticStore dataSourceDiagnosticStore = null; epf.Setup(f => f.CreateEventProcessor(It.IsAny <LdClientContext>())) .Callback((LdClientContext ctx) => eventProcessorDiagnosticStore = ctx.DiagnosticStore) .Returns(new ComponentsImpl.NullEventProcessor()); dsf.Setup(f => f.CreateDataSource(It.IsAny <LdClientContext>(), It.IsAny <IDataSourceUpdates>())) .Callback((LdClientContext ctx, IDataSourceUpdates dsu) => dataSourceDiagnosticStore = ctx.DiagnosticStore) .Returns((LdClientContext ctx, IDataSourceUpdates dsu) => dataSource); using (var client = new LdClient(config)) { epf.Verify(f => f.CreateEventProcessor(It.IsNotNull <LdClientContext>()), Times.Once()); epf.VerifyNoOtherCalls(); dsf.Verify(f => f.CreateDataSource(It.IsNotNull <LdClientContext>(), It.IsNotNull <IDataSourceUpdates>()), Times.Once()); dsf.VerifyNoOtherCalls(); Assert.Null(eventProcessorDiagnosticStore); Assert.Null(dataSourceDiagnosticStore); } }
public void DataSinceFromLastDiagnostic() { IDiagnosticStore _serverDiagnosticStore = CreateDiagnosticStore(null); DiagnosticEvent periodicEvent = _serverDiagnosticStore.CreateEventAndReset(); Assert.Equal(periodicEvent.JsonValue.Get("creationDate").AsLong, UnixMillisecondTime.FromDateTime(_serverDiagnosticStore.DataSince).Value); }
internal EventBuffer(int capacity, IDiagnosticStore diagnosticStore, Logger logger) { _capacity = capacity; _events = new List <object>(); _summarizer = new EventSummarizer(); _diagnosticStore = diagnosticStore; _logger = logger; }
public void DataSinceFromLastDiagnostic() { IDiagnosticStore _serverDiagnosticStore = CreateDiagnosticStore(); DiagnosticEvent periodicEvent = _serverDiagnosticStore.CreateEventAndReset(); Assert.Equal(periodicEvent.JsonValue.Get("creationDate").AsLong, Util.GetUnixTimestampMillis(_serverDiagnosticStore.DataSince)); }
public void CanIncrementDroppedEvents() { IDiagnosticStore _serverDiagnosticStore = CreateDiagnosticStore(); _serverDiagnosticStore.IncrementDroppedEvents(); DiagnosticEvent periodicEvent = _serverDiagnosticStore.CreateEventAndReset(); Assert.Equal(1, periodicEvent.JsonValue.Get("droppedEvents").AsInt); }
public void CanRecordEventsInBatch() { IDiagnosticStore _serverDiagnosticStore = CreateDiagnosticStore(); _serverDiagnosticStore.RecordEventsInBatch(4); DiagnosticEvent periodicEvent = _serverDiagnosticStore.CreateEventAndReset(); Assert.Equal(4, periodicEvent.JsonValue.Get("eventsInLastBatch").AsInt); }
public void CanIncrementDeduplicateUsers() { IDiagnosticStore _serverDiagnosticStore = CreateDiagnosticStore(null); _serverDiagnosticStore.IncrementDeduplicatedUsers(); DiagnosticEvent periodicEvent = _serverDiagnosticStore.CreateEventAndReset(); Assert.Equal(1, periodicEvent.JsonValue.Get("deduplicatedUsers").AsInt); }
private IDataSource MakeDataSourceWithDiagnostics(Uri baseUri, User user, IDiagnosticStore diagnosticStore) { var config = BasicConfig() .ServiceEndpoints(Components.ServiceEndpoints().Streaming(baseUri).Polling(baseUri)) .Build(); var context = new LdClientContext(config, null, diagnosticStore, null); return(Components.StreamingDataSource().InitialReconnectDelay(BriefReconnectDelay) .CreateDataSource(context, _updateSink, user, false)); }
public void PeriodicEventUsesIdFromInit() { IDiagnosticStore _serverDiagnosticStore = CreateDiagnosticStore(); DiagnosticEvent? initEvent = _serverDiagnosticStore.InitEvent; Assert.True(initEvent.HasValue); DiagnosticEvent periodicEvent = _serverDiagnosticStore.CreateEventAndReset(); Assert.Equal(initEvent.Value.JsonValue.Get("id"), periodicEvent.JsonValue.Get("id")); }
public EventProcessor( EventsConfiguration config, IEventSender eventSender, IUserDeduplicator userDeduplicator, IDiagnosticStore diagnosticStore, IDiagnosticDisabler diagnosticDisabler, Logger logger, Action testActionOnDiagnosticSend ) { _logger = logger; _stopped = new AtomicBoolean(false); _offline = new AtomicBoolean(false); _sentInitialDiagnostics = new AtomicBoolean(false); _inputCapacityExceeded = new AtomicBoolean(false); _messageQueue = new BlockingCollection <EventProcessorInternal.IEventMessage>( config.EventCapacity > 0 ? config.EventCapacity : 1); _processorInternal = new EventProcessorInternal( config, _messageQueue, eventSender, userDeduplicator, diagnosticStore, _logger, testActionOnDiagnosticSend ); if (config.EventFlushInterval > TimeSpan.Zero) { _flushTimer = new Timer(DoBackgroundFlush, null, config.EventFlushInterval, config.EventFlushInterval); } _diagnosticStore = diagnosticStore; _diagnosticRecordingInterval = config.DiagnosticRecordingInterval; if (userDeduplicator != null && userDeduplicator.FlushInterval.HasValue) { _flushUsersTimer = new Timer(DoUserKeysFlush, null, userDeduplicator.FlushInterval.Value, userDeduplicator.FlushInterval.Value); } else { _flushUsersTimer = null; } if (diagnosticStore != null) { SetupDiagnosticInit(diagnosticDisabler == null || !diagnosticDisabler.Disabled); if (diagnosticDisabler != null) { diagnosticDisabler.DisabledChanged += ((sender, args) => SetupDiagnosticInit(!args.Disabled)); } } }
internal LdClientContext( BasicConfiguration basic, HttpConfiguration http, IDiagnosticStore diagnosticStore, TaskExecutor taskExecutor ) { Basic = basic; Http = http; DiagnosticStore = diagnosticStore; TaskExecutor = taskExecutor; }
public void InitEventFieldsAreCorrect() { IDiagnosticStore _serverDiagnosticStore = CreateDiagnosticStore(); Assert.NotNull(_serverDiagnosticStore.InitEvent); LdValue initEvent = _serverDiagnosticStore.InitEvent.Value.JsonValue; Assert.Equal("diagnostic-init", initEvent.Get("kind").AsString); Assert.Equal(_expectedPlatform, initEvent.Get("platform")); Assert.Equal(_expectedSdk, initEvent.Get("sdk")); Assert.Equal(_expectedConfig, initEvent.Get("configuration")); Assert.Equal("DK_KEY", initEvent.Get("id").Get("sdkKeySuffix").AsString); Assert.Equal(Util.GetUnixTimestampMillis(_serverDiagnosticStore.DataSince), initEvent.Get("creationDate").AsLong); }
public IEventProcessor CreateEventProcessor(Configuration config, IDiagnosticStore diagnosticStore) { if (config.Offline) { return(new NullEventProcessor()); } else { return(new DefaultEventProcessor(config.EventProcessorConfiguration, new DefaultUserDeduplicator(config), Util.MakeHttpClient(config.HttpRequestConfiguration, ServerSideClientEnvironment.Instance), diagnosticStore, null, null)); } }
public void PeriodicEventDefaultValuesAreCorrect() { IDiagnosticStore _serverDiagnosticStore = CreateDiagnosticStore(); DateTime dataSince = _serverDiagnosticStore.DataSince; LdValue periodicEvent = _serverDiagnosticStore.CreateEventAndReset().JsonValue; Assert.Equal("diagnostic", periodicEvent.Get("kind").AsString); Assert.Equal(Util.GetUnixTimestampMillis(dataSince), periodicEvent.Get("dataSinceDate").AsLong); Assert.Equal(0, periodicEvent.Get("eventsInLastBatch").AsInt); Assert.Equal(0, periodicEvent.Get("droppedEvents").AsInt); Assert.Equal(0, periodicEvent.Get("deduplicatedUsers").AsInt); LdValue streamInits = periodicEvent.Get("streamInits"); Assert.Equal(0, streamInits.Count); }
public void CanAddStreamInit() { IDiagnosticStore _serverDiagnosticStore = CreateDiagnosticStore(); DateTime timestamp = DateTime.Now; _serverDiagnosticStore.AddStreamInit(timestamp, TimeSpan.FromMilliseconds(200.0), true); DiagnosticEvent periodicEvent = _serverDiagnosticStore.CreateEventAndReset(); LdValue streamInits = periodicEvent.JsonValue.Get("streamInits"); Assert.Equal(1, streamInits.Count); LdValue streamInit = streamInits.Get(0); Assert.Equal(Util.GetUnixTimestampMillis(timestamp), streamInit.Get("timestamp").AsLong); Assert.Equal(200, streamInit.Get("durationMillis").AsInt); Assert.Equal(true, streamInit.Get("failed").AsBool); }
public void CreatingEventResetsFields() { IDiagnosticStore _serverDiagnosticStore = CreateDiagnosticStore(); _serverDiagnosticStore.IncrementDroppedEvents(); _serverDiagnosticStore.IncrementDeduplicatedUsers(); _serverDiagnosticStore.RecordEventsInBatch(10); _serverDiagnosticStore.AddStreamInit(DateTime.Now, TimeSpan.FromMilliseconds(200.0), true); LdValue firstPeriodicEvent = _serverDiagnosticStore.CreateEventAndReset().JsonValue; LdValue nextPeriodicEvent = _serverDiagnosticStore.CreateEventAndReset().JsonValue; Assert.Equal(firstPeriodicEvent.Get("creationDate"), nextPeriodicEvent.Get("dataSinceDate")); Assert.Equal(0, nextPeriodicEvent.Get("eventsInLastBatch").AsInt); Assert.Equal(0, nextPeriodicEvent.Get("droppedEvents").AsInt); Assert.Equal(0, nextPeriodicEvent.Get("deduplicatedUsers").AsInt); Assert.Equal(0, nextPeriodicEvent.Get("eventsInLastBatch").AsInt); LdValue streamInits = nextPeriodicEvent.Get("streamInits"); Assert.Equal(0, streamInits.Count); }
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; }
private EventProcessor MakeProcessor(EventsConfiguration config, Mock <IEventSender> mockSender, IDiagnosticStore diagnosticStore, IDiagnosticDisabler diagnosticDisabler, CountdownEvent diagnosticCountdown) { return(new EventProcessor(config, mockSender.Object, new TestUserDeduplicator(), diagnosticStore, diagnosticDisabler, NullLogger, () => { diagnosticCountdown.Signal(); })); }
public IUpdateProcessor CreateUpdateProcessor(Configuration config, IFeatureStore featureStore, IDiagnosticStore diagnosticStore) { if (config.Offline) { Log.Info("Starting Launchdarkly client in offline mode."); return(new NullUpdateProcessor()); } else if (config.UseLdd) { Log.Info("Starting LaunchDarkly in LDD mode. Skipping direct feature retrieval."); return(new NullUpdateProcessor()); } else { FeatureRequestor requestor = new FeatureRequestor(config); if (config.IsStreamingEnabled) { return(new StreamProcessor(config, requestor, featureStore, null, diagnosticStore)); } else { Log.Warn("You should only disable the streaming API if instructed to do so by LaunchDarkly support"); return(new PollingProcessor(config, requestor, featureStore)); } } }
internal StreamProcessor(Configuration config, IFeatureRequestor featureRequestor, IFeatureStore featureStore, StreamManager.EventSourceCreator eventSourceCreator, IDiagnosticStore diagnosticStore) { _streamManager = new StreamManager(this, MakeStreamProperties(config), config.StreamManagerConfiguration, ServerSideClientEnvironment.Instance, eventSourceCreator, diagnosticStore); _config = config; _featureRequestor = featureRequestor; _featureStore = featureStore; }