< Summary

Information
Class: Elsa.Bpmn.Hosting.BpmnWorkLedger
Assembly: Elsa.Bpmn
File(s): /home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Bpmn/Hosting/BpmnWorkLedger.cs
Line coverage
100%
Covered lines: 7
Uncovered lines: 0
Coverable lines: 7
Total lines: 48
Line coverage: 100%
Branch coverage
N/A
Covered branches: 0
Total branches: 0
Branch coverage: N/A
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
get_Sequence()100%11100%
get_Records()100%11100%
NextHandle()100%11100%
FindByChildContextId(...)100%11100%
FindByHandle(...)100%11100%
Remove(...)100%11100%
ToLiveWork()100%11100%

File(s)

/home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Bpmn/Hosting/BpmnWorkLedger.cs

#LineLine coverage
 1using Bpmn.Semantics;
 2
 3namespace Elsa.Bpmn.Hosting;
 4
 5/// <summary>
 6/// A BPMN scope's record of the work it has started and not finished — the handle-to-context map, and the source of
 7/// <see cref="BpmnHostSnapshot.LiveWork"/>.
 8/// </summary>
 9/// <remarks>
 10/// <para>
 11/// What belongs in here depends on which callback the scope is about to make, and the difference is load-bearing:
 12/// completing and faulting work must already have been removed, because leaving it lets a re-armed non-interrupting
 13/// listener key onto the same <c>(binding ref, iteration id)</c> slot and a teardown then targets the work that just
 14/// finished; signalling work must still be present, because an escalating activity keeps running and removing it
 15/// makes the interpreter believe it has already gone.
 16/// </para>
 17/// <para>
 18/// The interpreter re-finds a parked token from <c>(binding ref, iteration id)</c> alone, so a scope must never hold
 19/// two live units of work under one such pair. Multi-instance instances share a binding ref and are told apart by
 20/// their iteration id, which is what it is for.
 21/// </para>
 22/// </remarks>
 23internal sealed class BpmnWorkLedger
 24{
 25    /// <summary>The handle counter. Handles are scope-local so a scope's trace reads independently of Elsa's id generat
 62726    public int Sequence { get; set; }
 27
 28    /// <summary>The live work, in start order.</summary>
 123929    public List<BpmnWorkRecord> Records { get; set; } = [];
 30
 31    /// <summary>Mints the next scope-local handle.</summary>
 10232    public string NextHandle() => $"work-{++Sequence}";
 33
 34    /// <summary>The live work running in the given child activity execution, or <c>null</c>.</summary>
 35    public BpmnWorkRecord? FindByChildContextId(string childContextId) =>
 20936        Records.FirstOrDefault(x => string.Equals(x.ChildContextId, childContextId, StringComparison.Ordinal));
 37
 38    /// <summary>The live work with the given handle, or <c>null</c>.</summary>
 39    public BpmnWorkRecord? FindByHandle(string handle) =>
 1640        Records.FirstOrDefault(x => string.Equals(x.Handle, handle, StringComparison.Ordinal));
 41
 42    /// <summary>Drops a record, so the work is no longer reported as live.</summary>
 9943    public void Remove(BpmnWorkRecord record) => Records.Remove(record);
 44
 45    /// <summary>The interpreter's view of this scope's live work.</summary>
 46    public IReadOnlyCollection<BpmnLiveWork> ToLiveWork() =>
 15647        Records.Select(x => new BpmnLiveWork(x.BindingRef, x.IterationId, x.Handle)).ToArray();
 48}