Example #1
0
        public void Dispose_can_be_called_multiple_times()
        {
            var subject = new HeartbeatDelay(TimeSpan.FromHours(10), TimeSpan.FromMilliseconds(1));

            subject.Dispose();
            subject.Dispose();
        }
        private async Task MonitorServerAsync()
        {
            var metronome = new Metronome(_settings.HeartbeatInterval);
            var heartbeatCancellationToken = _heartbeatCancellationTokenSource.Token;

            while (!heartbeatCancellationToken.IsCancellationRequested)
            {
                try
                {
                    await HeartbeatAsync(heartbeatCancellationToken).ConfigureAwait(false);

                    var newHeartbeatDelay = new HeartbeatDelay(metronome.GetNextTickDelay(), __minHeartbeatInterval);
                    var oldHeartbeatDelay = Interlocked.Exchange(ref _heartbeatDelay, newHeartbeatDelay);
                    if (oldHeartbeatDelay != null)
                    {
                        oldHeartbeatDelay.Dispose();
                    }
                    await newHeartbeatDelay.Task.ConfigureAwait(false);
                }
                catch
                {
                    // ignore these exceptions
                }
            }
        }
        public void Dispose_can_be_called_multiple_times()
        {
            var subject = new HeartbeatDelay(TimeSpan.FromHours(10), TimeSpan.FromMilliseconds(1));

            subject.Dispose();
            subject.Dispose();
        }
        // methods
        public void Initialize()
        {
            if (_state.TryChange(State.Initial, State.Open))
            {
                if (_listener != null)
                {
                    _listener.ServerBeforeOpening(new ServerBeforeOpeningEvent(_serverId, _settings));
                }

                var stopwatch = Stopwatch.StartNew();
                _connectionPool.Initialize();
                var metronome = new Metronome(_settings.HeartbeatInterval);
                AsyncBackgroundTask.Start(
                    HeartbeatAsync,
                    ct =>
                {
                    var newHeartbeatDelay = new HeartbeatDelay(metronome.GetNextTickDelay(), __minHeartbeatInterval);
                    var oldHeartbeatDelay = Interlocked.Exchange(ref _heartbeatDelay, newHeartbeatDelay);
                    if (oldHeartbeatDelay != null)
                    {
                        oldHeartbeatDelay.Dispose();
                    }
                    return(newHeartbeatDelay.Task);
                },
                    _heartbeatCancellationTokenSource.Token)
                .HandleUnobservedException(ex => { });     // TODO: do we need to do anything here?
                stopwatch.Stop();

                if (_listener != null)
                {
                    _listener.ServerAfterOpening(new ServerAfterOpeningEvent(_serverId, _settings, stopwatch.Elapsed));
                }
            }
        }
Example #5
0
        public void Task_should_complete_when_early_heartbeat_is_requested()
        {
            var subject = new HeartbeatDelay(TimeSpan.FromHours(10), TimeSpan.FromMilliseconds(1));

            subject.RequestHeartbeat();

            subject.Task.Wait(TimeSpan.FromSeconds(1)).Should().BeTrue();
        }
        public void Task_should_complete_when_early_heartbeat_is_requested()
        {
            var subject = new HeartbeatDelay(TimeSpan.FromHours(10), TimeSpan.FromMilliseconds(1));

            subject.RequestHeartbeat();

            subject.Task.Wait(TimeSpan.FromSeconds(1)).Should().BeTrue();
        }
Example #7
0
        public void RequestHeartbeat_should_respect_to_minHeartbeatInterval([Values(10, -1)] int heartbeatIntervalInMinutes)
        {
            var heartbeatInterval = heartbeatIntervalInMinutes == -1 ? Timeout.InfiniteTimeSpan : TimeSpan.FromMinutes(heartbeatIntervalInMinutes);
            var subject           = new HeartbeatDelay(heartbeatInterval, TimeSpan.FromSeconds(2));

            subject.RequestHeartbeat();

            SpinWait.SpinUntil(() => subject.Task.Status != TaskStatus.WaitingForActivation, TimeSpan.FromMilliseconds(1500)).Should().BeFalse();
            Thread.Sleep(TimeSpan.FromMilliseconds(700));
            subject.Task.Status.Should().Be(TaskStatus.RanToCompletion);
        }
        public void RequestHeartbeat_should_respect_to_minHeartbeatInterval([Values(10, -1)] int heartbeatIntervalInMinutes)
        {
            var heartbeatInterval    = heartbeatIntervalInMinutes == -1 ? Timeout.InfiniteTimeSpan : TimeSpan.FromMinutes(heartbeatIntervalInMinutes);
            var minHeartbeatInterval = TimeSpan.FromSeconds(2);

            var stopwatch = Stopwatch.StartNew();
            var subject   = new HeartbeatDelay(heartbeatInterval, minHeartbeatInterval);

            subject.RequestHeartbeat();
            var timeout = TimeSpan.FromMinutes(1);
            var result  = Task.WaitAny(subject.Task, Task.Delay(timeout));

            if (result != 0)
            {
                throw new Exception($"The test timeout {timeout} is exceeded.");
            }
            stopwatch.Stop();

            stopwatch.Elapsed.Should().BeGreaterOrEqualTo(minHeartbeatInterval - TimeSpan.FromMilliseconds(15));
        }
Example #9
0
        public void Task_should_complete_when_heartbeatInterval_has_expired()
        {
            var subject = new HeartbeatDelay(TimeSpan.FromMilliseconds(1), TimeSpan.FromMilliseconds(1));

            subject.Task.Wait(TimeSpan.FromSeconds(1)).Should().BeTrue();
        }
 private async Task MonitorServerAsync()
 {
     var metronome = new Metronome(_interval);
     var heartbeatCancellationToken = _cancellationTokenSource.Token;
     while (!heartbeatCancellationToken.IsCancellationRequested)
     {
         try
         {
             await HeartbeatAsync(heartbeatCancellationToken).ConfigureAwait(false);
             var newHeartbeatDelay = new HeartbeatDelay(metronome.GetNextTickDelay(), __minHeartbeatInterval);
             var oldHeartbeatDelay = Interlocked.Exchange(ref _heartbeatDelay, newHeartbeatDelay);
             if (oldHeartbeatDelay != null)
             {
                 oldHeartbeatDelay.Dispose();
             }
             await newHeartbeatDelay.Task.ConfigureAwait(false);
         }
         catch
         {
             // ignore these exceptions
         }
     }
 }
Example #11
0
        private async Task MonitorServerAsync()
        {
            var metronome = new Metronome(_heartbeatInterval);
            var heartbeatCancellationToken = _cancellationTokenSource.Token;

            while (!heartbeatCancellationToken.IsCancellationRequested)
            {
                try
                {
                    try
                    {
                        await HeartbeatAsync(heartbeatCancellationToken).ConfigureAwait(false);
                    }
                    catch (OperationCanceledException) when(heartbeatCancellationToken.IsCancellationRequested)
                    {
                        // ignore OperationCanceledException when heartbeat cancellation is requested
                    }
                    catch (Exception unexpectedException)
                    {
                        // if we catch an exception here it's because of a bug in the driver (but we need to defend ourselves against that)

                        var handler = _sdamInformationEventHandler;
                        if (handler != null)
                        {
                            try
                            {
                                handler.Invoke(new SdamInformationEvent(() =>
                                                                        string.Format(
                                                                            "Unexpected exception in ServerMonitor.MonitorServerAsync: {0}",
                                                                            unexpectedException.ToString())));
                            }
                            catch
                            {
                                // ignore any exceptions thrown by the handler (note: event handlers aren't supposed to throw exceptions)
                            }
                        }

                        // since an unexpected exception was thrown set the server description to Unknown (with the unexpected exception)
                        try
                        {
                            // keep this code as simple as possible to keep the surface area with any remaining possible bugs as small as possible
                            var newDescription = _baseDescription.WithHeartbeatException(unexpectedException); // not With in case the bug is in With
                            SetDescription(newDescription);                                                    // not SetDescriptionIfChanged in case the bug is in SetDescriptionIfChanged
                        }
                        catch
                        {
                            // if even the simple code in the try throws just give up (at least we've raised the unexpected exception via an SdamInformationEvent)
                        }
                    }

                    var newHeartbeatDelay = new HeartbeatDelay(metronome.GetNextTickDelay(), __minHeartbeatInterval);
                    var oldHeartbeatDelay = Interlocked.Exchange(ref _heartbeatDelay, newHeartbeatDelay);
                    if (oldHeartbeatDelay != null)
                    {
                        oldHeartbeatDelay.Dispose();
                    }
                    await newHeartbeatDelay.Task.ConfigureAwait(false);
                }
                catch
                {
                    // ignore these exceptions
                }
            }
        }
        private async Task MonitorServerAsync()
        {
            await Task.Yield(); // return control immediately

            var metronome = new Metronome(_serverMonitorSettings.HeartbeatInterval);
            var monitorCancellationToken = _monitorCancellationTokenSource.Token;

            while (!monitorCancellationToken.IsCancellationRequested)
            {
                try
                {
                    CancellationToken cachedHeartbeatCancellationToken;
                    lock (_lock)
                    {
                        cachedHeartbeatCancellationToken = _heartbeatCancellationTokenSource.Token; // we want to cache the current cancellation token in case the source changes
                    }

                    try
                    {
                        await HeartbeatAsync(cachedHeartbeatCancellationToken).ConfigureAwait(false);
                    }
                    catch (OperationCanceledException) when(cachedHeartbeatCancellationToken.IsCancellationRequested)
                    {
                        // ignore OperationCanceledException when heartbeat cancellation is requested
                    }
                    catch (Exception unexpectedException)
                    {
                        // if we catch an exception here it's because of a bug in the driver (but we need to defend ourselves against that)

                        var handler = _sdamInformationEventHandler;
                        if (handler != null)
                        {
                            try
                            {
                                handler.Invoke(new SdamInformationEvent(() =>
                                                                        string.Format(
                                                                            "Unexpected exception in ServerMonitor.MonitorServerAsync: {0}",
                                                                            unexpectedException.ToString())));
                            }
                            catch
                            {
                                // ignore any exceptions thrown by the handler (note: event handlers aren't supposed to throw exceptions)
                            }
                        }

                        // since an unexpected exception was thrown set the server description to Unknown (with the unexpected exception)
                        try
                        {
                            // keep this code as simple as possible to keep the surface area with any remaining possible bugs as small as possible
                            var newDescription = _baseDescription.WithHeartbeatException(unexpectedException); // not With in case the bug is in With
                            SetDescription(newDescription);                                                    // not SetDescriptionIfChanged in case the bug is in SetDescriptionIfChanged
                        }
                        catch
                        {
                            // if even the simple code in the try throws just give up (at least we've raised the unexpected exception via an SdamInformationEvent)
                        }
                    }

                    HeartbeatDelay newHeartbeatDelay;
                    lock (_lock)
                    {
                        newHeartbeatDelay = new HeartbeatDelay(metronome.GetNextTickDelay(), _serverMonitorSettings.MinHeartbeatInterval);
                        if (_heartbeatDelay != null)
                        {
                            _heartbeatDelay.Dispose();
                        }
                        _heartbeatDelay = newHeartbeatDelay;
                    }
                    await newHeartbeatDelay.Task.ConfigureAwait(false); // corresponds to wait method in spec
                }
                catch
                {
                    // ignore these exceptions
                }
            }
        }
        public void Task_should_complete_when_heartbeatInterval_has_expired()
        {
            var subject = new HeartbeatDelay(TimeSpan.FromMilliseconds(1), TimeSpan.FromMilliseconds(1));

            subject.Task.Wait(TimeSpan.FromSeconds(1)).Should().BeTrue();
        }