* feat(bpmn): host-side applier for the Bpmn.Semantics port Translates the interpreter's three host commands onto ActivityExecutionContext and feeds its four entry points, plus the minimum BpmnProcess container needed to exercise them end to end through IWorkflowRunner. StartWork schedules the bound activity, CancelWorkSubtree calls the public CancelActivityAsync extension (already recursive), and SignalEnclosingScope sends a BpmnScopeSignal up the ancestor chain. OnWorkFaulted rides the FaultSignal seam: it asks the interpreter what BPMN made of the fault and calls StopPropagation only on a Caught disposition, leaving a Propagated one strictly alone so an enclosing scope or the incident strategy takes it. A unit of work is keyed on the child ActivityExecutionContext.Id, recorded in the scope's own persisted ledger, never on Tag: the completion-callback dispatch rewrites the receiving context's Tag, so a nested scope wears a different tag than its parent remembers it by. Interpreter correlation travels on the child's context rather than on the shared activity instance. Evaluations go through one queue per workflow instance, so a scope signalled mid-apply is drained after the command list rather than re-entering the interpreter. Commands are applied in the order returned. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * test(bpmn): cover the teardown refusal path Adds a focused unit test that drives BpmnWorkTeardown.CancelSubtreeAsync into the NotSupportedException branch by constructing a real context tree with a scheduled-but-not-invoked descendant, so a regression that silently drops the detection is caught. Also records why BpmnWorkLedger's append-only, handle-keyed Records list cannot strand a context on a duplicate StartWork for a live (BindingRef, IterationId) slot, a case the port's own guarantee makes unreachable from this applier. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * fix(bpmn): keep a refused teardown from stranding ledger state A subtree cancellation refused with NotSupportedException is absorbed into an incident under ContinueWithIncidentsStrategy rather than crashing, so the end-of-command ledger save was being skipped and the persisted ledger kept claiming work BPMN had just torn down. Save the ledger removal before the possible throw instead of after, so a later completion callback for the stranded activity finds no live record and is discarded instead of being fed to the interpreter. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
27 lines
592 B
C#
27 lines
592 B
C#
using Elsa.Bpmn.Activities;
|
|
using Elsa.Extensions;
|
|
using Elsa.Features.Abstractions;
|
|
using Elsa.Features.Attributes;
|
|
using Elsa.Features.Services;
|
|
using Elsa.Workflows.Management.Features;
|
|
|
|
namespace Elsa.Bpmn.Features;
|
|
|
|
/// <summary>
|
|
/// Provides BPMN execution support to the system.
|
|
/// </summary>
|
|
[DependsOn(typeof(WorkflowManagementFeature))]
|
|
public class BpmnFeature : FeatureBase
|
|
{
|
|
/// <inheritdoc />
|
|
public BpmnFeature(IModule module) : base(module)
|
|
{
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public override void Apply()
|
|
{
|
|
Module.AddActivity<BpmnProcess>();
|
|
}
|
|
}
|