< Summary

Information
Class: Elsa.Workflows.Runtime.Services.ExecutionCycleAwareCommitStateHandler
Assembly: Elsa.Workflows.Runtime
File(s): /home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Workflows.Runtime/Services/ExecutionCycleAwareCommitStateHandler.cs
Line coverage
70%
Covered lines: 7
Uncovered lines: 3
Coverable lines: 10
Total lines: 42
Line coverage: 70%
Branch coverage
100%
Covered branches: 4
Total branches: 4
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%
CommitAsync()100%210%
CommitAsync()100%11100%
DisposeCycleHandleIfPresent(...)100%44100%

File(s)

/home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Workflows.Runtime/Services/ExecutionCycleAwareCommitStateHandler.cs

#LineLine coverage
 1using Elsa.Workflows.CommitStates;
 2using Elsa.Workflows.Runtime.Middleware.Workflows;
 3using Elsa.Workflows.State;
 4
 5namespace Elsa.Workflows.Runtime.Services;
 6
 7/// <summary>
 8/// Decorator that disposes the execution-cycle handle stored in
 9/// <see cref="WorkflowExecutionContext.TransientProperties"/> AFTER the inner commit handler has persisted the
 10/// workflow's terminal state. This ordering is essential for the drain orchestrator's force-cancel path: the
 11/// orchestrator awaits <see cref="ExecutionCycleHandle.Disposed"/> with a settle timeout before it overwrites the
 12/// persisted sub-status with <see cref="WorkflowSubStatus.Interrupted"/>. Without this decorator the handle would
 13/// dispose at the end of the pipeline middleware (i.e., BEFORE commit), the orchestrator's wait would complete
 14/// prematurely, and the orchestrator's <c>Interrupted</c> write would either find no instance row (early dispatches)
 15/// or be clobbered by the runner's subsequent commit (mid-execution dispatches).
 16/// </summary>
 17public sealed class ExecutionCycleAwareCommitStateHandler : ICommitStateHandler
 18{
 19    private readonly DefaultCommitStateHandler _inner;
 20
 104421    public ExecutionCycleAwareCommitStateHandler(DefaultCommitStateHandler inner) => _inner = inner;
 22
 23    /// <inheritdoc />
 24    public async Task CommitAsync(WorkflowExecutionContext workflowExecutionContext, CancellationToken cancellationToken
 25    {
 026        try { await _inner.CommitAsync(workflowExecutionContext, cancellationToken); }
 027        finally { DisposeCycleHandleIfPresent(workflowExecutionContext); }
 028    }
 29
 30    /// <inheritdoc />
 31    public async Task CommitAsync(WorkflowExecutionContext workflowExecutionContext, WorkflowState workflowState, Cancel
 32    {
 109033        try { await _inner.CommitAsync(workflowExecutionContext, workflowState, cancellationToken); }
 54534        finally { DisposeCycleHandleIfPresent(workflowExecutionContext); }
 54535    }
 36
 37    private static void DisposeCycleHandleIfPresent(WorkflowExecutionContext context)
 38    {
 54539        if (context.TransientProperties.TryGetValue(ExecutionCycleTrackingMiddleware.ExecutionCycleHandleKey, out var ra
 54540            handle.Dispose();
 54541    }
 42}