Exemple #1
0
 public void UpdateStatus(DataStoreStatus newStatus)
 {
     if (_status.Update(newStatus, out _))
     {
         _taskExecutor.ScheduleEvent(newStatus, StatusChanged);
     }
 }
 private void OnDataStoreStatusChanged(object sender, DataStoreStatus newStatus)
 {
     if (newStatus.Available && newStatus.RefreshNeeded)
     {
         // The store has just transitioned from unavailable to available, and we can't guarantee that
         // all of the latest data got cached, so let's restart the stream to refresh all the data.
         _log.Warn("Restarting stream to refresh data after data store outage");
         _es.Restart(false);
     }
 }
Exemple #3
0
        internal DataStoreUpdatesImpl(TaskExecutor taskExecutor, Logger log)
        {
            _taskExecutor = taskExecutor;
            var initialStatus = new DataStoreStatus
            {
                Available     = true,
                RefreshNeeded = false
            };

            _status = new StateMonitor <DataStoreStatus, DataStoreStatus>(initialStatus, MaybeUpdate, log);
        }
 public void UpdateStatus(DataStoreStatus newStatus)
 {
     lock (_stateLock)
     {
         if (newStatus.Equals(_currentStatus))
         {
             return;
         }
         _currentStatus = newStatus;
     }
     _taskExecutor.ScheduleEvent(this, newStatus, StatusChanged);
 }
Exemple #5
0
        internal void UpdateAvailability(bool available)
        {
            if (_lastAvailable.GetAndSet(available) == available)
            {
                return; // no change
            }

            var status = new DataStoreStatus
            {
                Available     = available,
                RefreshNeeded = available && _refreshOnRecovery
            };

            if (available)
            {
                _log.Warn("Persistent store is available again");
            }

            _statusUpdater(status);

            // If the store has just become unavailable, start a poller to detect when it comes back.
            // If it has become available, stop any polling we are currently doing.
            lock (_pollerLock)
            {
                if (available)
                {
                    _pollCanceller?.Cancel();
                    _pollCanceller = null;
                }
                else
                {
                    _log.Warn("Detected persistent store unavailability; updates will be cached until it recovers");

                    if (_pollCanceller is null)
                    {
                        // Start polling until the store starts working again
                        _pollCanceller = _taskExecutor.StartRepeatingTask(
                            PollInterval,
                            PollInterval,
                            () =>
                        {
                            if (_statusPollFn())
                            {
                                UpdateAvailability(true);
                            }
                            return(Task.FromResult(true));    // return value doesn't matter here
                        }
                            );
                    }
                }
            }
        }
Exemple #6
0
        public void UpdateStatusBroadcastsNewStatus()
        {
            var statuses = new EventSink <DataStoreStatus>();

            updates.StatusChanged += statuses.Add;

            var expectedStatus = new DataStoreStatus
            {
                Available     = false,
                RefreshNeeded = true
            };

            updates.UpdateStatus(expectedStatus);

            var newStatus = statuses.ExpectValue();

            Assert.Equal(expectedStatus, newStatus);
            statuses.ExpectNoValue();
        }
Exemple #7
0
        public void DataStoreStatusProviderSendsStatusUpdates()
        {
            var dataStoreFactory = new CapturingDataStoreFactory(Components.InMemoryDataStore);
            var config           = BasicConfig()
                                   .DataStore(dataStoreFactory)
                                   .Build();

            using (var client = new LdClient(config))
            {
                var statuses = new EventSink <DataStoreStatus>();
                client.DataStoreStatusProvider.StatusChanged += statuses.Add;

                var newStatus = new DataStoreStatus {
                    Available = false
                };
                dataStoreFactory.DataStoreUpdates.UpdateStatus(newStatus);

                Assert.Equal(newStatus, statuses.ExpectValue());
            }
        }
        public void Listeners()
        {
            var statuses = new EventSink <DataStoreStatus>();

            _dataStoreStatusProvider.StatusChanged += statuses.Add;

            var unwantedStatuses = new EventSink <DataStoreStatus>();

            _dataStoreStatusProvider.StatusChanged += unwantedStatuses.Add;
            _dataStoreStatusProvider.StatusChanged -= unwantedStatuses.Add; // testing that a listener can be removed

            var status = new DataStoreStatus {
                Available = false, RefreshNeeded = false
            };

            _dataStoreUpdates.UpdateStatus(status);

            Assert.Equal(status, statuses.ExpectValue());
            unwantedStatuses.ExpectNoValue();
        }
Exemple #9
0
        public void DataStoreStatusProviderReturnsLatestStatus()
        {
            var dataStoreFactory = new CapturingDataStoreFactory(Components.InMemoryDataStore);
            var config           = BasicConfig()
                                   .DataStore(dataStoreFactory)
                                   .Build();

            using (var client = new LdClient(config))
            {
                Assert.Equal(new DataStoreStatus {
                    Available = true
                },
                             client.DataStoreStatusProvider.Status);

                var newStatus = new DataStoreStatus {
                    Available = false
                };
                dataStoreFactory.DataStoreUpdates.UpdateStatus(newStatus);

                Assert.Equal(newStatus, client.DataStoreStatusProvider.Status);
            }
        }
        public void Status()
        {
            Assert.Equal(new DataStoreStatus {
                Available = true, RefreshNeeded = false
            },
                         _dataStoreStatusProvider.Status);

            var status1 = new DataStoreStatus {
                Available = false, RefreshNeeded = false
            };

            _dataStoreUpdates.UpdateStatus(status1);

            Assert.Equal(status1, _dataStoreStatusProvider.Status);

            var status2 = new DataStoreStatus {
                Available = false, RefreshNeeded = true
            };

            _dataStoreUpdates.UpdateStatus(status2);

            Assert.Equal(status2, _dataStoreStatusProvider.Status);
        }
        public void DataStoreStatusProviderReturnsLatestStatus()
        {
            var dataStoreFactory = new CapturingDataStoreFactory(Components.InMemoryDataStore);
            var config           = Configuration.Builder("")
                                   .DataSource(Components.ExternalUpdatesOnly)
                                   .DataStore(dataStoreFactory)
                                   .Events(Components.NoEvents)
                                   .Build();

            using (var client = new LdClient(config))
            {
                Assert.Equal(new DataStoreStatus {
                    Available = true
                },
                             client.DataStoreStatusProvider.Status);

                var newStatus = new DataStoreStatus {
                    Available = false
                };
                dataStoreFactory.DataStoreUpdates.UpdateStatus(newStatus);

                Assert.Equal(newStatus, client.DataStoreStatusProvider.Status);
            }
        }
Exemple #12
0
 private DataStoreStatus?MaybeUpdate(DataStoreStatus lastValue, DataStoreStatus newValue) =>
 newValue.Equals(lastValue) ? (DataStoreStatus?)null : newValue;