< Summary

Information
Class: Elsa.Workflows.Runtime.IngressSources.PassiveIngressSource
Assembly: Elsa.Workflows.Runtime
File(s): /home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Workflows.Runtime/IngressSources/PassiveIngressSource.cs
Line coverage
83%
Covered lines: 5
Uncovered lines: 1
Coverable lines: 6
Total lines: 56
Line coverage: 83.3%
Branch coverage
100%
Covered branches: 2
Total branches: 2
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
get_PauseTimeout()100%11100%
get_CurrentState()100%22100%
PauseAsync(...)100%11100%
ResumeAsync(...)100%210%

File(s)

/home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Workflows.Runtime/IngressSources/PassiveIngressSource.cs

#LineLine coverage
 1namespace Elsa.Workflows.Runtime.IngressSources;
 2
 3/// <summary>
 4/// Base class for <see cref="IIngressSource"/> implementations whose actual pause/resume
 5/// enforcement lives in another layer — request middleware, queue processor, scheduling
 6/// dispatcher — and which only need to surface their state in the runtime's diagnostic
 7/// registry. Subclasses provide a stable <see cref="Name"/> and may override
 8/// <see cref="PauseTimeout"/>; everything else is derived from the shared
 9/// <see cref="IQuiescenceSignal"/>.
 10/// </summary>
 11/// <remarks>
 12/// <para>
 13/// Use this base when your component already cooperates with <see cref="IQuiescenceSignal"/>
 14/// at its hot path (e.g. an ASP.NET Core middleware that returns <c>503 Service Unavailable</c>
 15/// while the runtime is not accepting new work, or a queue processor that consults the signal
 16/// at the top of each invocation). The adapter is then a passive observer: <c>PauseAsync</c>
 17/// / <c>ResumeAsync</c> are no-ops because there is nothing locally to start or stop, and
 18/// <see cref="CurrentState"/> reflects the signal directly so the orchestrator's
 19/// <c>DrainOutcome.Sources</c> and the admin status endpoint can show the source's state
 20/// without each adapter re-implementing the same five-line snippet.
 21/// </para>
 22/// <para>
 23/// Implement <see cref="IIngressSource"/> directly — not via this base — when the source owns
 24/// concrete pause/resume behavior. For example, a message-queue consumer that needs to call
 25/// <c>Pause()</c> on its underlying client, or an HTTP poller that must stop a background
 26/// loop, has work to do at pause time and should encode that work in its own
 27/// <c>PauseAsync</c> / <c>ResumeAsync</c> implementations.
 28/// </para>
 29/// </remarks>
 2330public abstract class PassiveIngressSource(IQuiescenceSignal signal) : IIngressSource
 31{
 2332    private readonly IQuiescenceSignal _signal = signal;
 33
 34    /// <inheritdoc />
 35    public abstract string Name { get; }
 36
 37    /// <inheritdoc />
 38    /// <remarks>
 39    /// Returns <see cref="TimeSpan.Zero"/> by default, which defers to the configured
 40    /// <c>GracefulShutdownOptions.IngressPauseTimeout</c>. Passive sources do no work at pause
 41    /// time, so any sub-second value is correct in practice; deferring to the option lets
 42    /// operators tune the value globally without per-source overrides. Subclasses may override
 43    /// to return a positive value if they have a reason to set their own per-source timeout.
 44    /// </remarks>
 1945    public virtual TimeSpan PauseTimeout => TimeSpan.Zero;
 46
 47    /// <inheritdoc />
 48    public IngressSourceState CurrentState =>
 249        _signal.IsAcceptingNewWork ? IngressSourceState.Running : IngressSourceState.Paused;
 50
 51    /// <inheritdoc />
 1952    public ValueTask PauseAsync(CancellationToken cancellationToken) => ValueTask.CompletedTask;
 53
 54    /// <inheritdoc />
 055    public ValueTask ResumeAsync(CancellationToken cancellationToken) => ValueTask.CompletedTask;
 56}