Fix orphaned completion callback handling

This commit is contained in:
Sipke Schoorstra 2023-08-26 02:02:02 +02:00
parent ca25b78457
commit 7358613653
3 changed files with 14 additions and 9 deletions

View file

@ -15,7 +15,7 @@ namespace Elsa.Scheduling.Activities;
/// <summary>
/// Delay execution for the specified amount of time.
/// </summary>
[Activity( "Elsa", "Scheduling", "Delay execution for the specified amount of time.")]
[Activity("Elsa", "Scheduling", "Delay execution for the specified amount of time.")]
public class Delay : Activity, IActivityPropertyDefaultValueProvider
{
/// <inheritdoc />
@ -67,7 +67,7 @@ public class Delay : Activity, IActivityPropertyDefaultValueProvider
[Input(
Description = "The timespan to delay workflow execution.",
DefaultValueProvider = typeof(Delay)
)]
)]
public Input<TimeSpan> TimeSpan { get; set; } = default!;
/// <inheritdoc />
@ -81,35 +81,35 @@ public class Delay : Activity, IActivityPropertyDefaultValueProvider
context.JournalData.Add("ResumeAt", resumeAt);
context.CreateBookmark(payload);
}
/// <summary>
/// Creates a new <see cref="Delay"/> from the specified number of milliseconds.
/// </summary>
public static Delay FromMilliseconds(
double value,
[CallerFilePath] string? source = default, [CallerLineNumber] int? line = default) => new(System.TimeSpan.FromMilliseconds(value), source, line);
/// <summary>
/// Creates a new <see cref="Delay"/> from the specified number of seconds.
/// </summary>
public static Delay FromSeconds(
double value,
[CallerFilePath] string? source = default, [CallerLineNumber] int? line = default) => new(System.TimeSpan.FromSeconds(value), source, line);
/// <summary>
/// Creates a new <see cref="Delay"/> from the specified number of minutes.
/// </summary>
public static Delay FromMinutes(
double value,
[CallerFilePath] string? source = default, [CallerLineNumber] int? line = default) => new(System.TimeSpan.FromMinutes(value), source, line);
/// <summary>
/// Creates a new <see cref="Delay"/> from the specified number of hours.
/// </summary>
public static Delay FromHours(
double value,
[CallerFilePath] string? source = default, [CallerLineNumber] int? line = default) => new(System.TimeSpan.FromHours(value), source, line);
/// <summary>
/// Creates a new <see cref="Delay"/> from the specified number of days.
/// </summary>

View file

@ -530,7 +530,7 @@ public class ActivityExecutionContext : IExecutionContext
/// </summary>
public void ClearCompletionCallbacks()
{
var entriesToRemove = WorkflowExecutionContext.CompletionCallbacks.Where(x => x.Owner == this || x.Child.Activity == Activity);
var entriesToRemove = WorkflowExecutionContext.CompletionCallbacks.Where(x => x.Owner == this);
WorkflowExecutionContext.RemoveCompletionCallbacks(entriesToRemove);
}

View file

@ -65,7 +65,12 @@ public class WorkflowExecutionContextMapper : IWorkflowExecutionContextMapper
foreach (var completionCallbackEntry in state.CompletionCallbacks)
{
var ownerActivityExecutionContext = workflowExecutionContext.ActiveActivityExecutionContexts.First(x => x.Id == completionCallbackEntry.OwnerInstanceId);
var childNode = workflowExecutionContext.ActiveActivityExecutionContexts.First(x => x.NodeId == completionCallbackEntry.ChildNodeId).ActivityNode;
var childNode = workflowExecutionContext.ActiveActivityExecutionContexts.FirstOrDefault(x => x.NodeId == completionCallbackEntry.ChildNodeId)?.ActivityNode;
// If the child node is null, it means the completion callback was registered for an activity instance that has already completed or was canceled.
if(childNode == null)
continue;
var callbackName = completionCallbackEntry.MethodName;
var callbackDelegate = !string.IsNullOrEmpty(callbackName) ? ownerActivityExecutionContext.Activity.GetActivityCompletionCallback(callbackName) : default;
workflowExecutionContext.AddCompletionCallback(ownerActivityExecutionContext, childNode, callbackDelegate);