| | | 1 | | using CShells.Lifecycle; |
| | | 2 | | using Elsa.Workflows.Runtime.Services; |
| | | 3 | | using Microsoft.Extensions.Hosting; |
| | | 4 | | using Microsoft.Extensions.Logging; |
| | | 5 | | |
| | | 6 | | namespace Elsa.Workflows.Runtime.Lifecycle; |
| | | 7 | | |
| | | 8 | | /// <summary> |
| | | 9 | | /// CShells <see cref="IDrainHandler"/> that bridges per-shell drain into the workflow runtime's |
| | | 10 | | /// <see cref="IDrainOrchestrator"/>. The shell platform invokes this when a shell enters |
| | | 11 | | /// <see cref="ShellLifecycleState.Draining"/> (e.g., on shell reload or host shutdown). The drain handler's |
| | | 12 | | /// <see cref="CancellationToken"/> is signalled when the CShells drain deadline elapses, so the orchestrator's |
| | | 13 | | /// own deadline-bounded protocol nests cleanly inside the per-shell deadline policy. |
| | | 14 | | /// </summary> |
| | | 15 | | /// <remarks> |
| | | 16 | | /// <para> |
| | | 17 | | /// Registered as transient via <c>IShellFeature.ConfigureServices</c>; CShells resolves all |
| | | 18 | | /// <see cref="IDrainHandler"/> implementations from the shell's <see cref="IServiceProvider"/> at draining time |
| | | 19 | | /// and invokes them in parallel. This gives FR-027 ("a shell moving into its deactivation phase drains that |
| | | 20 | | /// shell's runtime, scoped so sibling shells are unaffected") a first-class, per-shell mechanism — replacing |
| | | 21 | | /// the earlier R3 design that relied on <c>IHostApplicationLifetime.ApplicationStopping</c>. |
| | | 22 | | /// </para> |
| | | 23 | | /// <para> |
| | | 24 | | /// In CShells-hosted deployments this is the sole drain trigger: host stop reaches the runtime via CShells's |
| | | 25 | | /// shell-drain pipeline (<c>CShellsStartupHostedService.StopAsync</c>), not via a host-level |
| | | 26 | | /// <see cref="IHostedService"/>. The host-stop <c>DrainOrchestratorHostedService</c> registration only lives on |
| | | 27 | | /// the IModule <c>Features/WorkflowRuntimeFeature</c> path, where there is no shell platform. |
| | | 28 | | /// </para> |
| | | 29 | | /// </remarks> |
| | 0 | 30 | | public sealed class ElsaShellDrainHandler(IDrainOrchestrator orchestrator, ILogger<ElsaShellDrainHandler> logger) : IDra |
| | | 31 | | { |
| | | 32 | | /// <inheritdoc /> |
| | | 33 | | public Task DrainAsync(IDrainExtensionHandle extensionHandle, CancellationToken cancellationToken) => |
| | 0 | 34 | | DrainTriggerExecutor.RunAsync(orchestrator, DrainTrigger.ShellDeactivation, logger, "Shell drain", cancellationT |
| | | 35 | | } |