diff --git a/examples/ConductorSharp.Definitions/appsettings.json b/examples/ConductorSharp.Definitions/appsettings.json index c3c5ffd3..fa169067 100644 --- a/examples/ConductorSharp.Definitions/appsettings.json +++ b/examples/ConductorSharp.Definitions/appsettings.json @@ -5,6 +5,6 @@ "LongPollInterval": 100, "MaxConcurrentWorkers": 10, "SleepInterval": 500, - "PreventErrorOnBadRequest": true + "PreventErrorOnBadRequest": false } } diff --git a/src/ConductorSharp.Engine/Service/WorkflowEngineBackgroundService.cs b/src/ConductorSharp.Engine/Service/WorkflowEngineBackgroundService.cs index 89dee1dd..c047b3f3 100644 --- a/src/ConductorSharp.Engine/Service/WorkflowEngineBackgroundService.cs +++ b/src/ConductorSharp.Engine/Service/WorkflowEngineBackgroundService.cs @@ -1,19 +1,32 @@ using ConductorSharp.Engine.Interface; using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; +using System; using System.Threading; using System.Threading.Tasks; namespace ConductorSharp.Engine.Service { - public class WorkflowEngineBackgroundService : IHostedService + public class WorkflowEngineBackgroundService : IHostedService, IDisposable { + private readonly ILogger _logger; + private readonly IHostApplicationLifetime _hostApplicationLifetime; private readonly IDeploymentService _deploymentService; private readonly ExecutionManager _executionManager; private readonly ModuleDeployment _deployment; private Task _executingTask; + private readonly CancellationTokenSource _stoppingCts = new(); - public WorkflowEngineBackgroundService(IDeploymentService deploymentService, ExecutionManager executionManager, ModuleDeployment deployment) + public WorkflowEngineBackgroundService( + ILogger logger, + IHostApplicationLifetime hostApplicationLifetime, + IDeploymentService deploymentService, + ExecutionManager executionManager, + ModuleDeployment deployment + ) { + _logger = logger; + _hostApplicationLifetime = hostApplicationLifetime; _deploymentService = deploymentService; _executionManager = executionManager; _deployment = deployment; @@ -21,16 +34,55 @@ public WorkflowEngineBackgroundService(IDeploymentService deploymentService, Exe public Task StartAsync(CancellationToken cancellationToken) { - _executingTask = RunAsync(cancellationToken); + _executingTask = RunAsync(_stoppingCts.Token); + + if (_executingTask.IsCompleted) + { + return _executingTask; + } + return Task.CompletedTask; } private async Task RunAsync(CancellationToken cancellationToken) { - await _deploymentService.Deploy(_deployment); - await _executionManager.StartAsync(cancellationToken); + try + { + await _deploymentService.Deploy(_deployment); + await _executionManager.StartAsync(cancellationToken); + } + catch (Exception exception) + { + _logger.LogCritical(exception, "Workflow Engine Background Service encountered an error"); + throw; + } + finally + { + _hostApplicationLifetime.StopApplication(); + } + } + + public async Task StopAsync(CancellationToken cancellationToken) + { + if (_executingTask == null) + { + return; + } + + try + { + _stoppingCts.Cancel(); + } + finally + { + _logger.LogDebug("Stopping Workflow Engine Background Service"); + await Task.WhenAny(_executingTask, Task.Delay(Timeout.Infinite, cancellationToken)); + } } - public async Task StopAsync(CancellationToken cancellationToken) => await _executingTask; + public virtual void Dispose() + { + _stoppingCts.Cancel(); + } } }