Move completion callback logic to base Activity
This commit is contained in:
parent
4ff2c228c4
commit
77ef383865
|
|
@ -13,7 +13,6 @@ public abstract class Container : Activity, IContainer
|
|||
{
|
||||
protected Container()
|
||||
{
|
||||
OnSignalReceived<ActivityCompleted>(OnChildActivityCompletedAsync);
|
||||
}
|
||||
|
||||
protected Container(params IActivity[] activities) : this()
|
||||
|
|
@ -36,23 +35,6 @@ public abstract class Container : Activity, IContainer
|
|||
|
||||
// Schedule children.
|
||||
await ScheduleChildrenAsync(context);
|
||||
|
||||
// Because we override ExecuteAsync, this activity will not automatically complete.
|
||||
// Instead, it's up to the derived classes to explicitly complete this activity.
|
||||
}
|
||||
|
||||
protected virtual async ValueTask OnChildActivityCompletedAsync(ActivityCompleted signal, SignalContext context)
|
||||
{
|
||||
var activityExecutionContext = context.ActivityExecutionContext;
|
||||
var ownerActivity = activityExecutionContext.Activity;
|
||||
var childActivityExecutionContext = context.SourceActivityExecutionContext;
|
||||
var childActivity = childActivityExecutionContext.Activity;
|
||||
var callbackEntry = activityExecutionContext.WorkflowExecutionContext.CompletionCallbacks.FirstOrDefault(x => x.Owner.Activity == ownerActivity && x.Child == childActivity);
|
||||
|
||||
if (callbackEntry == null)
|
||||
return;
|
||||
|
||||
await callbackEntry.CompletionCallback(activityExecutionContext, childActivityExecutionContext);
|
||||
}
|
||||
|
||||
protected virtual ValueTask ScheduleChildrenAsync(ActivityExecutionContext context)
|
||||
|
|
|
|||
|
|
@ -31,37 +31,41 @@ public class ForEach : Activity
|
|||
/// </summary>
|
||||
public Variable CurrentValue { get; set; } = new();
|
||||
|
||||
protected override void Execute(ActivityExecutionContext context)
|
||||
protected override bool CompleteImplicitly => false;
|
||||
|
||||
protected override async ValueTask ExecuteAsync(ActivityExecutionContext context)
|
||||
{
|
||||
// Declare looping variable.
|
||||
context.ExpressionExecutionContext.Register.Declare(CurrentValue);
|
||||
|
||||
// Execute first iteration.
|
||||
HandleIteration(context);
|
||||
await HandleIteration(context);
|
||||
}
|
||||
|
||||
private void HandleIteration(ActivityExecutionContext context)
|
||||
private async Task HandleIteration(ActivityExecutionContext context)
|
||||
{
|
||||
var currentIndex = context.GetProperty<int>(CurrentIndexProperty);
|
||||
var items = context.Get(Items)!.ToList();
|
||||
|
||||
if (currentIndex >= items.Count)
|
||||
{
|
||||
await context.CompleteActivityAsync();
|
||||
return;
|
||||
}
|
||||
|
||||
var currentItem = items[currentIndex];
|
||||
CurrentValue.Set(context, currentItem);
|
||||
|
||||
if (Body != null)
|
||||
context.PostActivity(Body, OnChildCompleted);
|
||||
context.ScheduleActivity(Body, OnChildCompleted);
|
||||
|
||||
// Increment index.
|
||||
context.UpdateProperty<int>(CurrentIndexProperty, x => x + 1);
|
||||
}
|
||||
|
||||
private ValueTask OnChildCompleted(ActivityExecutionContext context, ActivityExecutionContext childContext)
|
||||
private async ValueTask OnChildCompleted(ActivityExecutionContext context, ActivityExecutionContext childContext)
|
||||
{
|
||||
HandleIteration(context);
|
||||
return ValueTask.CompletedTask;
|
||||
await HandleIteration(context);
|
||||
}
|
||||
|
||||
private void OnBreak(BreakSignal signal, SignalContext context)
|
||||
|
|
|
|||
|
|
@ -8,19 +8,35 @@ namespace Elsa.Models;
|
|||
public abstract class Activity : ISignalHandler
|
||||
{
|
||||
private readonly ICollection<SignalHandlerRegistration> _signalHandlers = new List<SignalHandlerRegistration>();
|
||||
protected Activity() => TypeName = TypeNameHelper.GenerateTypeName(GetType());
|
||||
protected Activity(string activityType) => TypeName = activityType;
|
||||
protected Activity()
|
||||
{
|
||||
TypeName = TypeNameHelper.GenerateTypeName(GetType());
|
||||
OnSignalReceived<ActivityCompleted>(OnChildActivityCompletedAsync);
|
||||
}
|
||||
|
||||
protected Activity(string activityType) : this()
|
||||
{
|
||||
TypeName = activityType;
|
||||
}
|
||||
|
||||
public string Id { get; set; } = default!;
|
||||
public string TypeName { get; set; }
|
||||
public bool CanStartWorkflow { get; set; }
|
||||
public IDictionary<string, object> ApplicationProperties { get; set; } = new Dictionary<string, object>();
|
||||
public IDictionary<string, object> Metadata { get; set; } = new Dictionary<string, object>();
|
||||
|
||||
/// <summary>
|
||||
/// A value indicating whether this activity should complete automatically.
|
||||
/// Default is true.
|
||||
/// </summary>
|
||||
protected virtual bool CompleteImplicitly => true;
|
||||
|
||||
protected virtual async ValueTask ExecuteAsync(ActivityExecutionContext context)
|
||||
{
|
||||
Execute(context);
|
||||
await CompleteAsync(context);
|
||||
|
||||
if(CompleteImplicitly)
|
||||
await CompleteAsync(context);
|
||||
}
|
||||
|
||||
protected virtual ValueTask OnSignalReceivedAsync(object signal, SignalContext context)
|
||||
|
|
@ -56,6 +72,20 @@ public abstract class Activity : ISignalHandler
|
|||
return ValueTask.CompletedTask;
|
||||
});
|
||||
}
|
||||
|
||||
protected virtual async ValueTask OnChildActivityCompletedAsync(ActivityCompleted signal, SignalContext context)
|
||||
{
|
||||
var activityExecutionContext = context.ActivityExecutionContext;
|
||||
var ownerActivity = activityExecutionContext.Activity;
|
||||
var childActivityExecutionContext = context.SourceActivityExecutionContext;
|
||||
var childActivity = childActivityExecutionContext.Activity;
|
||||
var callbackEntry = activityExecutionContext.WorkflowExecutionContext.CompletionCallbacks.FirstOrDefault(x => x.Owner.Activity == ownerActivity && x.Child == childActivity);
|
||||
|
||||
if (callbackEntry == null)
|
||||
return;
|
||||
|
||||
await callbackEntry.CompletionCallback(activityExecutionContext, childActivityExecutionContext);
|
||||
}
|
||||
|
||||
async ValueTask IActivity.ExecuteAsync(ActivityExecutionContext context)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue