Пример #1
0
        /// <inheritdoc />
        public async Task RunAsync(IInfiniteDeadManSwitchWorker worker, DeadManSwitchOptions options, CancellationToken cancellationToken)
        {
            if (worker == null)
            {
                throw new ArgumentNullException(nameof(worker));
            }

            _logger.Trace("Starting infinite worker loop for {WorkerName} using a dead man's switch", worker.Name);

            using (var deadManSwitchSession = _deadManSwitchSessionFactory.Create(options))
                using (var watcherCTS = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken))
                {
                    var deadManSwitch        = deadManSwitchSession.DeadManSwitch;
                    var deadManSwitchWatcher = deadManSwitchSession.DeadManSwitchWatcher;
                    var deadManSwitchContext = deadManSwitchSession.DeadManSwitchContext;
                    var watcherTask          = Task.Factory.StartNew(() => deadManSwitchWatcher.WatchAsync(watcherCTS.Token), CancellationToken.None, TaskCreationOptions.LongRunning,
                                                                     TaskScheduler.Default);
                    var iteration = 1;
                    while (!cancellationToken.IsCancellationRequested)
                    {
                        using (var workerCTS = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, deadManSwitchContext.CancellationToken))
                        {
                            _logger.Trace("Beginning work iteration {Iteration} of infinite worker {WorkerName} using a dead man's switch", iteration, worker.Name);

                            var workerTask = Task.Run(() => worker.WorkAsync(deadManSwitch, workerCTS.Token), CancellationToken.None);

                            try
                            {
                                await workerTask.ConfigureAwait(false);

                                _logger.Debug("Worker {WorkerName} completed gracefully", worker.Name);

                                deadManSwitch.Notify("Worker task completed gracefully");
                            }
                            catch (OperationCanceledException)
                            {
                                _logger.Warning("Worker {WorkerName} was canceled", worker.Name);

                                // Restart watcher
                                await watcherTask.ConfigureAwait(false);

                                deadManSwitch.Notify("Worker task was canceled");

                                watcherTask = Task.Factory.StartNew(() => deadManSwitchWatcher.WatchAsync(watcherCTS.Token), CancellationToken.None, TaskCreationOptions.LongRunning,
                                                                    TaskScheduler.Default);
                            }
                        }

                        iteration++;
                    }

                    _logger.Information("Cancellation requested, cleaning up infinite worker loop for {WorkerName}", worker.Name);

                    watcherCTS.Cancel();
                    await watcherTask.ConfigureAwait(false);
                }

            _logger.Trace("Infinite worker loop for {WorkerName} has stopped", worker.Name);
        }
        /// <inheritdoc />
        public async Task <TResult> RunAsync <TResult>(IDeadManSwitchWorker <TResult> worker, DeadManSwitchOptions options,
                                                       CancellationToken cancellationToken)
        {
            if (worker == null)
            {
                throw new ArgumentNullException(nameof(worker));
            }

            using (var deadManSwitchSession = _deadManSwitchSessionFactory.Create(options))
                using (var watcherCTS = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken))
                    using (var workerCTS = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, deadManSwitchSession.DeadManSwitchContext.CancellationTokenSource.Token))
                    {
                        _logger.Trace("Running worker {WorkerName} using a dead man's switch", worker.Name);

                        var deadManSwitch        = deadManSwitchSession.DeadManSwitch;
                        var deadManSwitchWatcher = deadManSwitchSession.DeadManSwitchWatcher;

                        var workerTask  = Task.Run(async() => await worker.WorkAsync(deadManSwitch, workerCTS.Token).ConfigureAwait(false), CancellationToken.None);
                        var watcherTask = Task.Run(async() => await deadManSwitchWatcher.WatchAsync(watcherCTS.Token).ConfigureAwait(false), CancellationToken.None);

                        var task = await Task.WhenAny(workerTask, watcherTask).ConfigureAwait(false);

                        if (task == workerTask)
                        {
                            watcherCTS.Cancel();
                            return(await workerTask.ConfigureAwait(false));
                        }

                        workerCTS.Cancel();
                        throw new OperationCanceledException(workerCTS.Token);
                    }
        }
Пример #3
0
        public void Trigger()
        {
            _logger.Warning("The worker task did not notify the dead man's switch within the agreed timeout of {TimeoutInSeconds}s " +
                            "and will be cancelled.", _deadManSwitchOptions.Timeout.TotalSeconds);

            var notifications = _deadManSwitchContext.Notifications.ToArray();

            _logger.Warning("These were the last {NotificationCount} notifications: ", notifications.Length);

            foreach (var notification in notifications)
            {
                _logger.Warning("{NotificationTimestamp} {NotificationContent}", notification.Timestamp, notification.Content);
            }

            _logger.Trace("Marking worker cancellation token as cancelled");
            _deadManSwitchContext.Cancel();
        }
Пример #4
0
        public async ValueTask TriggerAsync(CancellationToken cancellationToken)
        {
            _logger.Warning("The worker task did not notify the dead man's switch within the agreed timeout of {TimeoutInSeconds}s " +
                            "and will be cancelled.", _deadManSwitchOptions.Timeout.TotalSeconds);

            var notifications = (await _deadManSwitchContext.GetNotificationsAsync(cancellationToken).ConfigureAwait(false)).ToList();

            _logger.Warning("These were the last {NotificationCount} notifications: ", notifications.Count);

            foreach (var notification in notifications)
            {
                _logger.Warning("{NotificationTimestamp} {NotificationContent}", notification.Timestamp, notification.Content);
            }

            var cancellationTokenSource = _deadManSwitchContext.CancellationTokenSource;

            _deadManSwitchContext.CancellationTokenSource = new CancellationTokenSource();

            _logger.Trace("Marking worker cancellation token as cancelled");
            cancellationTokenSource.Cancel();
            cancellationTokenSource.Dispose();
        }