Beispiel #1
0
        public async Task ShouldCancelTheTaskIfTheDeadManSwitchWasPausedAndResumedAndTheTaskTakesTooLong()
        {
            using (var cts = new CancellationTokenSource())
            {
                // Arrange
                double?pi = null, e = null;
                var    options = new DeadManSwitchOptions {
                    Timeout = TimeSpan.FromSeconds(2)
                };
                var workItems = WorkItems(
                    Work(
                        Pause(),
                        Sleep(TimeSpan.FromSeconds(3)),
                        Do(_ => pi = Math.PI),
                        Resume(),
                        Sleep(TimeSpan.FromSeconds(3)),
                        Do(_ => e = Math.E)
                        ),
                    Work(
                        Do(_ => _logger.LogInformation("Cancelling infinite worker")),
                        Do(_ => cts.Cancel())
                        )
                    );
                var worker = InfiniteWorker(workItems);

                // Act
                await _runner.RunAsync(worker, options, cts.Token).ConfigureAwait(false);

                // Assert
                pi.Should().NotBeNull();
                e.Should().BeNull();
            }
        }
        public async Task ShouldNotCancelTheTaskIfTheDeadManSwitchIsPausedMultipleTimesAndTheTaskTakesTooLong()
        {
            using (var cts = new CancellationTokenSource())
            {
                // Arrange
                var options = new DeadManSwitchOptions {
                    Timeout = TimeSpan.FromSeconds(2)
                };
                var worker = Worker(
                    Work(
                        Pause(),
                        Sleep(TimeSpan.FromSeconds(3)),
                        Pause(),
                        Pause(),
                        Resume()
                        ),
                    Result(Math.PI)
                    );

                // Act
                var result = await _runner.RunAsync(worker, options, cts.Token).ConfigureAwait(false);

                // Assert
                result.Should().Be(Math.PI);
            }
        }
        public async Task ShouldCancelTheTaskIfItTakesTooLongAfterResuming()
        {
            using (var cts = new CancellationTokenSource())
            {
                // Arrange
                double?e       = null;
                var    options = new DeadManSwitchOptions {
                    Timeout = TimeSpan.FromSeconds(2)
                };
                var worker = Worker(
                    Work(
                        Pause(),
                        Notify("Sleeping 3s"),
                        Sleep(TimeSpan.FromSeconds(3)),
                        Notify("Calculating PI"),
                        Resume(),
                        Notify("Sleeping 3s"),
                        Sleep(TimeSpan.FromSeconds(3)),
                        Notify("Calculating E"),
                        Do(_ => e = Math.E)
                        ),
                    Result(Math.PI)
                    );

                // Act
                await _runner.Invoking(m => m.RunAsync(worker, options, cts.Token)).Should().ThrowAsync <OperationCanceledException>().ConfigureAwait(false);

                // Assert
                e.Should().BeNull();
            }
        }
Beispiel #4
0
        public async Task ShouldCancelTheTaskWhenTasksTimeOutAndWhenCancelling()
        {
            using (var cts = new CancellationTokenSource())
            {
                // Arrange
                double?pi      = null;
                var    options = new DeadManSwitchOptions {
                    Timeout = TimeSpan.FromSeconds(3)
                };
                var workItems = WorkItems(
                    Work(
                        Sleep(TimeSpan.FromSeconds(4)),
                        Do(_ => pi = Math.PI)
                        ),
                    Work(
                        Do(_ => _logger.LogInformation("Cancelling infinite worker")),
                        Do(_ => cts.Cancel())
                        )
                    );
                var worker = InfiniteWorker(workItems);

                // Act
                var run = _runner.RunAsync(worker, options, cts.Token);
                await Task.Delay(TimeSpan.FromMilliseconds(10)).ConfigureAwait(false);

                cts.Cancel();
                await run.ConfigureAwait(false);

                // Assert
                pi.Should().BeNull();
            }
        }
        public async Task ShouldNotCancelTheTaskIfItTakesTooLongAfterPausingAndResumingAndPausingAgain()
        {
            using (var cts = new CancellationTokenSource())
            {
                // Arrange
                double?e       = null;
                var    options = new DeadManSwitchOptions {
                    Timeout = TimeSpan.FromSeconds(4)
                };
                var worker = Worker(
                    Work(
                        Pause(),
                        Notify("Sleeping 6s"),
                        Sleep(TimeSpan.FromSeconds(6)),
                        Notify("Calculating PI"),
                        Resume(),
                        Pause(),
                        Notify("Sleeping 6s"),
                        Sleep(TimeSpan.FromSeconds(6)),
                        Notify("Calculating E"),
                        Do(_ => e = Math.E)
                        ),
                    Result(Math.PI)
                    );

                // Act
                var result = await _runner.RunAsync(worker, options, cts.Token).ConfigureAwait(false);

                // Assert
                result.Should().Be(Math.PI);
                e.Should().Be(Math.E);
            }
        }
Beispiel #6
0
        public async Task ShouldRunTaskMultipleTimesUntilStopped()
        {
            using (var cts = new CancellationTokenSource())
            {
                // Arrange
                var pies    = new List <double>();
                var options = new DeadManSwitchOptions {
                    Timeout = TimeSpan.FromSeconds(2)
                };
                var worker = InfiniteWorker(
                    WorkItems(
                        Work(
                            Do(_ => pies.Add(Math.PI))
                            ),
                        Work(
                            Do(_ => pies.Add(Math.PI))),
                        Work(
                            Do(_ => pies.Add(Math.PI))
                            ),
                        Work(
                            Do(_ => _logger.LogInformation("Cancelling infinite worker")),
                            Do(_ => cts.Cancel())
                            )
                        ));

                // Act
                await _runner.RunAsync(worker, options, cts.Token).ConfigureAwait(false);

                // Assert
                pies.Should().HaveCount(3);
                pies.Should().AllBeEquivalentTo(Math.PI);
            }
        }
        public async Task ShouldHandleNotificationsInParallel(int numberOfNotifications)
        {
            using (var cts = new CancellationTokenSource())
            {
                // Arrange
                var options = new DeadManSwitchOptions {
                    Timeout = TimeSpan.FromSeconds(5), NumberOfNotificationsToKeep = 3
                };
                var worker = Worker(
                    Work(
                        async(deadManSwitch, cancellationToken) =>
                {
                    var sendNotifications = Enumerable.Range(0, numberOfNotifications)
                                            .AsParallel()
                                            .WithDegreeOfParallelism(100)
                                            .Select(i => Task.Run(() => deadManSwitch.Notify("Notification " + i)));
                    await Task.WhenAll(sendNotifications).ConfigureAwait(false);
                }
                        ),
                    Result(Math.PI)
                    );

                // Act
                var result = await _runner.RunAsync(worker, options, cts.Token).ConfigureAwait(false);

                // Assert
                result.Should().Be(Math.PI);
                _sessionFactory.Session.Should().NotBeNull();
                var notifications = _sessionFactory.Session.DeadManSwitchContext.Notifications;
                notifications.Should().HaveCount(3);
            }
        }
        public async Task ShouldContainNotificationsRespectingNumberOfNotificationsToKeep()
        {
            using (var cts = new CancellationTokenSource())
            {
                // Arrange
                var options = new DeadManSwitchOptions {
                    Timeout = TimeSpan.FromSeconds(5), NumberOfNotificationsToKeep = 3
                };
                var worker = Worker(
                    Work(
                        Notify("Notification 1"),
                        Notify("Notification 2"),
                        Notify("Notification 3"),
                        Notify("Notification 4")
                        ),
                    Result(Math.PI)
                    );

                // Act
                var result = await _runner.RunAsync(worker, options, cts.Token).ConfigureAwait(false);

                // Assert
                result.Should().Be(Math.PI);
                _sessionFactory.Session.Should().NotBeNull();
                var      notifications = _sessionFactory.Session.DeadManSwitchContext.Notifications;
                string[] expected      =
                {
                    "Notification 2",
                    "Notification 3",
                    "Notification 4"
                };
                var actual = notifications.Select(n => n.Content).ToArray();
                actual.Should().BeEquivalentTo(expected);
            }
        }
Beispiel #9
0
        /// <summary>
        /// Demonstrates how to run (and stop) an infinite worker, using a dead man's switch
        /// </summary>
        public static async Task Main()
        {
            var serviceProvider = new ServiceCollection()
                                  .AddLogging(builder => builder.AddConsole())
                                  .AddDeadManSwitch()
                                  .BuildServiceProvider();

            var infiniteRunner = serviceProvider.GetRequiredService <IInfiniteDeadManSwitchRunner>();
            var worker         = new ExampleInfiniteWorker();

            using (var cancellationTokenSource = new CancellationTokenSource())
            {
                var options = new DeadManSwitchOptions
                {
                    Timeout = TimeSpan.FromSeconds(60)
                };
                // do not await this, it will never complete until you cancel the token
                var run = infiniteRunner.RunAsync(worker, options, cancellationTokenSource.Token);

                // let it run for 10s.
                await Task.Delay(TimeSpan.FromSeconds(10), cancellationTokenSource.Token).ConfigureAwait(false);

                // now stop the infinite worker
                cancellationTokenSource.Cancel();

                // let it finish gracefully
                await run.ConfigureAwait(false);
            }
        }
        /// <summary>
        /// Demonstrates how to run (and stop) an infinite worker, using a dead man's switch
        /// </summary>
        public static async Task Main()
        {
            // This example uses NLog, but it only requires a trivial amount of code to use any other logging library
            var loggerFactory = new NLoggerFactory();

            var infiniteRunner = InfiniteDeadManSwitchRunner.Create(loggerFactory);
            var worker         = new ExampleInfiniteWorker();

            using (var cancellationTokenSource = new CancellationTokenSource())
            {
                var options = new DeadManSwitchOptions
                {
                    Timeout = TimeSpan.FromSeconds(60)
                };
                // do not await this, it will never complete until you cancel the token
                var run = infiniteRunner.RunAsync(worker, options, cancellationTokenSource.Token);

                // let it run for 10s.
                await Task.Delay(TimeSpan.FromSeconds(10), cancellationTokenSource.Token).ConfigureAwait(false);

                // now stop the infinite worker
                cancellationTokenSource.Cancel();

                // let it finish gracefully
                await run.ConfigureAwait(false);
            }
        }
        public async Task ShouldCancelTheTaskWhenTheTokenIsCancelled()
        {
            using (var cts = new CancellationTokenSource())
            {
                // Arrange
                var options = new DeadManSwitchOptions {
                    Timeout = TimeSpan.FromSeconds(2)
                };
                var worker = Worker(
                    Work(
                        Sleep(TimeSpan.FromSeconds(3))
                        ),
                    Result(Math.PI)
                    );

                // Act
                var runTask = _runner.RunAsync(worker, options, cts.Token);

                await Task.Delay(TimeSpan.FromSeconds(0.5)).ConfigureAwait(false);

                cts.Cancel();

                await runTask.Invoking(async task => await task.ConfigureAwait(false)).Should().ThrowAsync <OperationCanceledException>().ConfigureAwait(false);
            }
        }
        public async Task ShouldCancelTheTaskIfItTakesTooLongToDoSomethingAndThenBeAbleToRunAgainAndCompleteImmediately()
        {
            using (var cts = new CancellationTokenSource())
            {
                // Arrange
                var options = new DeadManSwitchOptions {
                    Timeout = TimeSpan.FromSeconds(2)
                };
                var worker = Worker(
                    Work(
                        Notify("Computing PI"),
                        Sleep(TimeSpan.FromSeconds(3))),
                    Result(Math.PI)
                    );

                // Act + Assert
                await _runner.Invoking(m => m.RunAsync(worker, options, cts.Token)).Should().ThrowAsync <OperationCanceledException>().ConfigureAwait(false);

                // Arrange
                worker = Worker(
                    Work(
                        Notify("Computing PI"),
                        Sleep(TimeSpan.FromSeconds(1))
                        ),
                    Result(Math.PI)
                    );

                // Act
                var result = await _runner.RunAsync(worker, options, cts.Token).ConfigureAwait(false);

                // Assert
                result.Should().Be(Math.PI);
            }
        }
Beispiel #13
0
        public DeadManSwitchContext(DeadManSwitchOptions deadManSwitchOptions)
        {
            if (deadManSwitchOptions == null)
            {
                throw new ArgumentNullException(nameof(deadManSwitchOptions));
            }

            var notifications = Channel.CreateBounded <DeadManSwitchNotification>(new BoundedChannelOptions(deadManSwitchOptions.NumberOfNotificationsToKeep)
            {
                SingleWriter = false,
                SingleReader = true,
                FullMode     = BoundedChannelFullMode.DropOldest
            });
            var statuses = Channel.CreateUnbounded <DeadManSwitchStatus>(new UnboundedChannelOptions
            {
                SingleWriter = false,
                SingleReader = true
            });

            _numberOfNotificationsToKeep = deadManSwitchOptions.NumberOfNotificationsToKeep;
            _notificationsReader         = notifications.Reader;
            _notificationsWriter         = notifications.Writer;
            _statusesReader = statuses.Reader;
            _statusesWriter = statuses.Writer;

            CancellationTokenSource = new CancellationTokenSource();
        }
        /// <summary>
        ///     Demonstrates how you can run a worker once, using a dead man's switch
        /// </summary>
        public static async Task Main()
        {
            // This example uses NLog, but it only requires a trivial amount of code to use any other logging library.
            var loggerFactory = new NLoggerFactory();

            // You can also use Create() which disables logging
            var runner = DeadManSwitchRunner.Create(loggerFactory);

            var worker = new ExampleWorker();

            using (var cancellationTokenSource = new CancellationTokenSource())
            {
                var options = new DeadManSwitchOptions
                {
                    Timeout = TimeSpan.FromSeconds(60)
                };
                var run = runner.RunAsync(worker, options, cancellationTokenSource.Token);

                // if you want to cancel at some point: cancellationTokenSource.Cancel();

                var result = await run.ConfigureAwait(false);

                Debug.Assert(result == Math.PI);
            }
        }
        /// <summary>
        ///     Demonstrates how you can run a worker once, using a dead man's switch
        /// </summary>
        public static async Task Main()
        {
            var serviceProvider = new ServiceCollection()
                                  .AddLogging(builder => builder.AddConsole())
                                  .AddDeadManSwitch()
                                  .BuildServiceProvider();
            var runner = serviceProvider.GetRequiredService <IDeadManSwitchRunner>();

            var worker = new ExampleWorker();

            using (var cancellationTokenSource = new CancellationTokenSource())
            {
                var options = new DeadManSwitchOptions
                {
                    Timeout = TimeSpan.FromSeconds(60)
                };
                var run = runner.RunAsync(worker, options, cancellationTokenSource.Token);

                // if you want to cancel at some point: cancellationTokenSource.Cancel();

                var result = await run.ConfigureAwait(false);

                Debug.Assert(result.Equals(Math.PI));
            }
        }
        public async Task ShouldLetTaskFinishIfItNotifiesTheDeadManSwitchWithinTheTimeout()
        {
            using (var cts = new CancellationTokenSource())
            {
                // Arrange
                var options = new DeadManSwitchOptions {
                    Timeout = TimeSpan.FromSeconds(2)
                };
                var worker = Worker(
                    Work(
                        Notify("Sleeping for 1 second"),
                        Sleep(TimeSpan.FromSeconds(1)),
                        Notify("Sleeping for 1 second"),
                        Sleep(TimeSpan.FromSeconds(1)),
                        Notify("Sleeping for 1 second"),
                        Sleep(TimeSpan.FromSeconds(1)),
                        Notify("Computing PI")
                        ),
                    Result(Math.PI)
                    );

                // Act
                var result = await _runner.RunAsync(worker, options, cts.Token).ConfigureAwait(false);

                // Assert
                result.Should().Be(Math.PI);
            }
        }
        /// <summary>
        ///     Demonstrates how to run (and stop) an infinite worker, using a dead man's switch
        /// </summary>
        public static async Task Main()
        {
            using (var cancellationTokenSource = new CancellationTokenSource())
            {
                var options = new DeadManSwitchOptions
                {
                    Timeout = TimeSpan.FromSeconds(60)
                };
                // do not await this, it will never complete until you cancel the token
                var run = InfiniteDeadManSwitchTask.RunAsync(async(deadManSwitch, cancellationToken) =>
                {
                    deadManSwitch.Notify("Beginning work again");

                    await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken).ConfigureAwait(false);

                    deadManSwitch.Notify("Still busy, please don't cancel");

                    await DoSomethingUseful(cancellationToken).ConfigureAwait(false);
                }, options, cancellationTokenSource.Token);

                // let it run for 10s.
                await Task.Delay(TimeSpan.FromSeconds(10), cancellationTokenSource.Token).ConfigureAwait(false);

                // now stop the infinite worker
                cancellationTokenSource.Cancel();

                // let it finish gracefully
                await run.ConfigureAwait(false);
            }
        }
        /// <summary>
        ///     Demonstrates how you can run a worker once, using a dead man's switch
        /// </summary>
        public static async Task Main()
        {
            using (var cancellationTokenSource = new CancellationTokenSource())
            {
                var options = new DeadManSwitchOptions
                {
                    Timeout = TimeSpan.FromSeconds(60)
                };
                var run = DeadManSwitchTask.RunAsync(async(deadManSwitch, cancellationToken) =>
                {
                    deadManSwitch.Notify("Beginning work");

                    await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken).ConfigureAwait(false);

                    deadManSwitch.Notify("Still busy, please don't cancel");

                    // tell the dead man's switch to stop the clock
                    deadManSwitch.Suspend();

                    // tell the dead man's switch to resume the clock
                    deadManSwitch.Resume();

                    return(Math.PI);
                }, options, cancellationTokenSource.Token);

                // if you want to cancel at some point: cancellationTokenSource.Cancel();

                var result = await run.ConfigureAwait(false);

                Debug.Assert(result.Equals(Math.PI));
            }
        }
Beispiel #19
0
 public DeadManSwitchContext(DeadManSwitchOptions deadManSwitchOptions)
 {
     _deadManSwitchOptions       = deadManSwitchOptions ?? throw new ArgumentNullException(nameof(deadManSwitchOptions));
     _notifications              = new DeadManSwitchNotification[_deadManSwitchOptions.NumberOfNotificationsToKeep];
     _lastNotifiedTicks          = DateTime.UtcNow.Ticks;
     _notificationsNextItemIndex = 0;
     _notificationsSyncRoot      = new object();
     _cancellationTokenSource    = new CancellationTokenSource();
 }
Beispiel #20
0
 public DeadManSwitchWatcher(IDeadManSwitchContext deadManSwitchContext,
                             DeadManSwitchOptions deadManSwitchOptions,
                             IDeadManSwitchTriggerer deadManSwitchTriggerer,
                             IDeadManSwitchLogger <DeadManSwitchWatcher> logger)
 {
     _context = deadManSwitchContext ?? throw new ArgumentNullException(nameof(deadManSwitchContext));
     _options = deadManSwitchOptions ?? throw new ArgumentNullException(nameof(deadManSwitchOptions));
     _deadManSwitchTriggerer = deadManSwitchTriggerer ?? throw new ArgumentNullException(nameof(deadManSwitchTriggerer));
     _logger = logger ?? throw new ArgumentNullException(nameof(logger));
 }
 public DeadManSwitchBenchmarks()
 {
     _deadManSwitchRunner         = DeadManSwitchRunner.Create();
     _infiniteDeadManSwitchRunner = InfiniteDeadManSwitchRunner.Create();
     _deadManSwitchOptions        = new DeadManSwitchOptions
     {
         Timeout = TimeSpan.FromSeconds(1),
         NumberOfNotificationsToKeep = 5
     };
 }
        public IDeadManSwitchSession Create(DeadManSwitchOptions deadManSwitchOptions)
        {
            var deadManSwitchContext   = new DeadManSwitchContext(deadManSwitchOptions);
            var deadManSwitch          = new DeadManSwitch(deadManSwitchContext, _loggerFactory.CreateLogger <DeadManSwitch>());
            var deadManSwitchTriggerer = new DeadManSwitchTriggerer(deadManSwitchContext, deadManSwitchOptions, _loggerFactory.CreateLogger <DeadManSwitchTriggerer>());
            var deadManSwitchWatcher   =
                new DeadManSwitchWatcher(deadManSwitchContext, deadManSwitchOptions, deadManSwitchTriggerer, _loggerFactory.CreateLogger <DeadManSwitchWatcher>());

            return(new DeadManSwitchSession(deadManSwitchContext, deadManSwitch, deadManSwitchWatcher));
        }
        public async Task ShouldLetTaskFinishIfItCompletesImmediately()
        {
            using (var cts = new CancellationTokenSource())
            {
                // Arrange
                var timeout = TimeSpan.FromSeconds(2);
                var worker  = Worker(Work(), Result(Math.PI));
                var options = new DeadManSwitchOptions {
                    Timeout = timeout
                };

                // Act
                var result = await _runner.RunAsync(worker, options, cts.Token).ConfigureAwait(false);

                // Assert
                result.Should().Be(Math.PI);
            }
        }
        public async Task ShouldCancelTheTaskIfItTakesTooLongWithoutEverNotifyingTheDeadManSwitch()
        {
            using (var cts = new CancellationTokenSource())
            {
                // Arrange
                var options = new DeadManSwitchOptions {
                    Timeout = TimeSpan.FromSeconds(2)
                };
                var worker = Worker(
                    Work(
                        Sleep(TimeSpan.FromSeconds(3))
                        ),
                    Result(Math.PI)
                    );

                // Act + Assert
                await _runner.Invoking(m => m.RunAsync(worker, options, cts.Token)).Should().ThrowAsync <OperationCanceledException>().ConfigureAwait(false);
            }
        }
Beispiel #25
0
        /// <summary>
        /// Demonstrates how you can run a worker once, using a dead man's switch
        /// </summary>
        public static async Task Main()
        {
            var loggerFactory = new NLoggerFactory();
            var runner        = DeadManSwitchRunner.Create(loggerFactory);

            var worker = new ExampleWorker();

            using (var cancellationTokenSource = new CancellationTokenSource())
            {
                var options = new DeadManSwitchOptions
                {
                    Timeout = TimeSpan.FromSeconds(60)
                };
                var run = runner.RunAsync(worker, options, cancellationTokenSource.Token);

                // if you want to cancel at some point: cancellationTokenSource.Cancel();

                var result = await run.ConfigureAwait(false);

                Debug.Assert(result == Math.PI);
            }
        }
        public async Task ShouldLetTaskFinishIfItRunsQuicklyEnoughWithoutDeadManSwitchNotifications()
        {
            using (var cts = new CancellationTokenSource())
            {
                // Arrange
                var options = new DeadManSwitchOptions {
                    Timeout = TimeSpan.FromSeconds(2)
                };
                var worker = Worker(
                    Work(
                        Sleep(TimeSpan.FromSeconds(1))
                        ),
                    Result(Math.PI)
                    );

                // Act
                var result = await _runner.RunAsync(worker, options, cts.Token).ConfigureAwait(false);

                // Assert
                result.Should().Be(Math.PI);
            }
        }
Beispiel #27
0
        public async Task ShouldNotStopTaskIfTaskIsNotifyingTheDeadManSwitch()
        {
            using (var cts = new CancellationTokenSource())
            {
                // Arrange
                double?pi      = null;
                double?e       = null;
                var    options = new DeadManSwitchOptions {
                    Timeout = TimeSpan.FromSeconds(2)
                };
                var workItems = WorkItems(
                    Work(
                        Notify("Going to sleep for 1 second"),
                        Sleep(TimeSpan.FromSeconds(1)),
                        Notify("Going to sleep for 1 second"),
                        Sleep(TimeSpan.FromSeconds(1)),
                        Notify("Going to sleep for 1 second"),
                        Sleep(TimeSpan.FromSeconds(1)),
                        Do(_ => e = Math.E)
                        ),
                    Work(
                        Do(_ => pi = Math.PI)
                        ),
                    Work(
                        Do(_ => _logger.LogInformation("Cancelling infinite worker")),
                        Do(_ => cts.Cancel())
                        )
                    );
                var worker = InfiniteWorker(workItems);

                // Act
                await _runner.RunAsync(worker, options, cts.Token).ConfigureAwait(false);

                // Assert
                e.Should().Be(Math.E);
                pi.Should().Be(Math.PI);
            }
        }
        public async Task ShouldCancelTheTaskIfItTakesTooLongSynchronously()
        {
            using (var cts = new CancellationTokenSource())
            {
                // Arrange
                var options = new DeadManSwitchOptions {
                    Timeout = TimeSpan.FromSeconds(5)
                };
                var worker = Worker(
                    Work(
                        (deadManSwitch, cancellationToken) =>
                {
                    Thread.Sleep(6000);
                    return(Task.CompletedTask);
                }
                        ),
                    Result(Math.PI)
                    );

                // Act
                await _runner.Invoking(m => m.RunAsync(worker, options, cts.Token)).Should().ThrowAsync <OperationCanceledException>().ConfigureAwait(false);
            }
        }
Beispiel #29
0
        public async Task ShouldLetTaskFinishIfItCompletesImmediately()
        {
            using (var cts = new CancellationTokenSource())
            {
                // Arrange
                double?pi      = null;
                var    options = new DeadManSwitchOptions {
                    Timeout = TimeSpan.FromSeconds(2)
                };
                var workItems = WorkItems(
                    Work(Do(_ => pi = Math.PI)),
                    Do(_ => _logger.LogInformation("Cancelling infinite worker")),
                    Work(Do(_ => cts.Cancel()))
                    );
                var worker = InfiniteWorker(workItems);

                // Act
                await _runner.RunAsync(worker, options, cts.Token).ConfigureAwait(false);

                // Assert
                pi.Should().Be(Math.PI);
            }
        }
Beispiel #30
0
        public async Task ShouldRunTaskAgainAfterStoppingItTheFirstTime()
        {
            using (var cts = new CancellationTokenSource())
            {
                // Arrange
                double?pi      = null;
                double?e       = null;
                var    options = new DeadManSwitchOptions {
                    Timeout = TimeSpan.FromSeconds(2)
                };
                var workItems = WorkItems(
                    Work(
                        Notify("Going to sleep for 5 seconds"),
                        Do(_ => _logger.LogInformation("In loop 1, this should be cancelled")),
                        Sleep(TimeSpan.FromSeconds(5)),
                        Do(_ => _logger.LogInformation("In loop 1, task was not aborted!!!")),
                        Do(_ => e = Math.E)
                        ),
                    Work(
                        Do(_ => _logger.LogInformation("In loop 2, assigning Math.PI")),
                        Do(_ => pi = Math.PI)
                        ),
                    Work(
                        Do(_ => _logger.LogInformation("In loop 3, stopping worker")),
                        Do(_ => cts.Cancel())
                        )
                    );
                var worker = InfiniteWorker(workItems);

                // Act
                await _runner.RunAsync(worker, options, cts.Token).ConfigureAwait(false);

                // Assert
                e.Should().BeNull();
                pi.Should().Be(Math.PI);
            }
        }