using CShells.Lifecycle; using Elsa.Workflows.Runtime.Services; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; namespace Elsa.Workflows.Runtime.Lifecycle; /// /// CShells that bridges per-shell drain into the workflow runtime's /// . The shell platform invokes this when a shell enters /// (e.g., on shell reload or host shutdown). The drain handler's /// is signalled when the CShells drain deadline elapses, so the orchestrator's /// own deadline-bounded protocol nests cleanly inside the per-shell deadline policy. /// /// /// /// Registered as transient via IShellFeature.ConfigureServices; CShells resolves all /// implementations from the shell's at draining time /// and invokes them in parallel. This gives FR-027 ("a shell moving into its deactivation phase drains that /// shell's runtime, scoped so sibling shells are unaffected") a first-class, per-shell mechanism — replacing /// the earlier R3 design that relied on IHostApplicationLifetime.ApplicationStopping. /// /// /// In CShells-hosted deployments this is the sole drain trigger: host stop reaches the runtime via CShells's /// shell-drain pipeline (CShellsStartupHostedService.StopAsync), not via a host-level /// . The host-stop DrainOrchestratorHostedService registration only lives on /// the IModule Features/WorkflowRuntimeFeature path, where there is no shell platform. /// /// public sealed class ElsaShellDrainHandler(IDrainOrchestrator orchestrator, ILogger logger) : IDrainHandler { /// public Task DrainAsync(IDrainExtensionHandle extensionHandle, CancellationToken cancellationToken) => DrainTriggerExecutor.RunAsync(orchestrator, DrainTrigger.ShellDeactivation, logger, "Shell drain", cancellationToken); }