Merge pull request #6213 from elsa-workflows/bug/6170
Refactor activity cancellation and bookmark handling.
This commit is contained in:
commit
5d92c5760f
|
|
@ -1,7 +1,6 @@
|
|||
using System.Collections.Immutable;
|
||||
using System.ComponentModel;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Elsa.Extensions;
|
||||
using Elsa.Workflows.Attributes;
|
||||
using Elsa.Workflows.Signals;
|
||||
using Elsa.Workflows.UIHints;
|
||||
|
|
@ -18,7 +17,7 @@ namespace Elsa.Workflows.Activities;
|
|||
public class Fork : Activity
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public Fork([CallerFilePath] string? source = default, [CallerLineNumber] int? line = default) : base(source, line)
|
||||
public Fork([CallerFilePath] string? source = null, [CallerLineNumber] int? line = null) : base(source, line)
|
||||
{
|
||||
// Handle break signals directly instead of using the BreakBehavior. The behavior stops propagation of the signal, which is not what we want.
|
||||
OnSignalReceived<BreakSignal>(OnBreakSignalReceived);
|
||||
|
|
@ -48,13 +47,7 @@ public class Fork : Activity
|
|||
|
||||
if (isBreaking)
|
||||
{
|
||||
// Remove all bookmarks from other branches.
|
||||
RemoveBookmarks(targetContext);
|
||||
|
||||
// Signal activity completion.
|
||||
await CompleteAsync(targetContext);
|
||||
|
||||
// Exit.
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -75,37 +68,15 @@ public class Fork : Activity
|
|||
switch (joinMode)
|
||||
{
|
||||
case ForkJoinMode.WaitAny:
|
||||
{
|
||||
// Remove all bookmarks from other branches.
|
||||
RemoveBookmarks(targetContext);
|
||||
|
||||
// Signal activity completion.
|
||||
await CompleteAsync(targetContext);
|
||||
}
|
||||
break;
|
||||
case ForkJoinMode.WaitAll:
|
||||
{
|
||||
var allSet = allChildActivityIds.All(x => completedActivityIds.Contains(x));
|
||||
|
||||
if (allSet)
|
||||
// Signal activity completion.
|
||||
await CompleteAsync(targetContext);
|
||||
}
|
||||
if (allSet) await CompleteAsync(targetContext);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void RemoveBookmarks(ActivityExecutionContext context)
|
||||
{
|
||||
// Find all descendants for each branch and remove them as well as any associated bookmarks.
|
||||
var workflowExecutionContext = context.WorkflowExecutionContext;
|
||||
var forkNode = context.ActivityNode;
|
||||
var branchNodes = forkNode.Children;
|
||||
var branchDescendantActivityIds = branchNodes.SelectMany(x => x.Flatten()).Select(x => x.Activity.Id).ToHashSet();
|
||||
|
||||
workflowExecutionContext.Bookmarks.RemoveWhere(x => branchDescendantActivityIds.Contains(x.ActivityId));
|
||||
}
|
||||
|
||||
private void OnBreakSignalReceived(BreakSignal signal, SignalContext signalContext)
|
||||
{
|
||||
signalContext.ReceiverActivityExecutionContext.SetIsBreaking();
|
||||
|
|
|
|||
|
|
@ -23,13 +23,19 @@ public partial class ActivityExecutionContext
|
|||
ClearBookmarks();
|
||||
ClearCompletionCallbacks();
|
||||
WorkflowExecutionContext.Bookmarks.RemoveWhere(x => x.ActivityNodeId == NodeId);
|
||||
|
||||
// Add an execution log entry.
|
||||
AddExecutionLogEntry("Canceled", payload: JournalData);
|
||||
|
||||
await this.SendSignalAsync(new CancelSignal());
|
||||
await CancelChildActivitiesAsync();
|
||||
|
||||
// ReSharper disable once MethodSupportsCancellation
|
||||
await _publisher.SendAsync(new ActivityCancelled(this));
|
||||
}
|
||||
|
||||
private async Task CancelChildActivitiesAsync()
|
||||
{
|
||||
var childContexts = WorkflowExecutionContext.ActivityExecutionContexts.Where(x => x.ParentActivityExecutionContext == this && x.CanCancelActivity()).ToList();
|
||||
|
||||
foreach (var childContext in childContexts)
|
||||
await childContext.CancelActivityAsync();
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue