Improving behaviour of Run Asynchronously property for the TaskActivityAttribute
This commit is contained in:
parent
dd8a6f5866
commit
1bf9b11ffc
|
|
@ -68,7 +68,7 @@ public abstract class Activity : IActivity, ISignalHandler
|
|||
/// will execute synchronously, while activities of the <see cref="ActivityKind.Job"/> kind will execute asynchronously.
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public bool RunAsynchronously
|
||||
public bool? RunAsynchronously
|
||||
{
|
||||
get => this.GetRunAsynchronously();
|
||||
set => this.SetRunAsynchronously(value);
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ public static class ActivityPropertyExtensions
|
|||
/// Gets a flag indicating whether this activity can be used for starting a workflow.
|
||||
/// Usually used for triggers, but also used to disambiguate between two or more starting activities and no starting activity was specified.
|
||||
/// </summary>
|
||||
public static bool GetCanStartWorkflow(this IActivity activity) => activity.CustomProperties.GetValueOrDefault(CanStartWorkflowPropertyName, () => false);
|
||||
public static bool GetCanStartWorkflow(this IActivity activity) => activity.CustomProperties.GetValueOrDefault<bool>(CanStartWorkflowPropertyName, () => false);
|
||||
|
||||
/// <summary>
|
||||
/// Sets a flag indicating whether this activity can be used for starting a workflow.
|
||||
|
|
@ -29,14 +29,17 @@ public static class ActivityPropertyExtensions
|
|||
/// By default, activities with an <see cref="ActivityKind"/> of <see cref="Action"/>, <see cref="Task"/> or <see cref="Trigger"/>
|
||||
/// will execute synchronously, while activities of the <see cref="ActivityKind.Job"/> kind will execute asynchronously.
|
||||
/// </summary>
|
||||
public static bool GetRunAsynchronously(this IActivity activity) => activity.CustomProperties.GetValueOrDefault(RunAsynchronouslyPropertyName, () => false);
|
||||
public static bool? GetRunAsynchronously(this IActivity activity)
|
||||
{
|
||||
return activity.CustomProperties.GetValueOrDefault<bool?>(RunAsynchronouslyPropertyName, defaultValueFactory: () => null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets a flag indicating if this activity should execute synchronously or asynchronously.
|
||||
/// By default, activities with an <see cref="ActivityKind"/> of <see cref="Action"/>, <see cref="Task"/> or <see cref="Trigger"/>
|
||||
/// will execute synchronously, while activities of the <see cref="ActivityKind.Job"/> kind will execute asynchronously.
|
||||
/// </summary>
|
||||
public static void SetRunAsynchronously(this IActivity activity, bool value) => activity.CustomProperties[RunAsynchronouslyPropertyName[0]] = value;
|
||||
public static void SetRunAsynchronously(this IActivity activity, bool? value) => activity.CustomProperties[RunAsynchronouslyPropertyName[0]] = value;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the source file and line number where this activity was instantiated, if any.
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
using System.Text.Json.Nodes;
|
||||
using Elsa.Expressions.Helpers;
|
||||
using Elsa.Extensions;
|
||||
using Elsa.Workflows.Attributes;
|
||||
using Elsa.Workflows.Memory;
|
||||
using Elsa.Workflows.Models;
|
||||
using Humanizer;
|
||||
|
|
@ -34,7 +35,18 @@ public class ActivityFactory : IActivityFactory
|
|||
|
||||
// 7) Pull out your boolean flags from the cleaned element
|
||||
var canStartWorkflow = GetBoolean(cleanedElement, "canStartWorkflow");
|
||||
var runAsynchronously = GetBoolean(cleanedElement, "runAsynchronously");
|
||||
var runAsynchronously = GetNullableBoolean(cleanedElement, "runAsynchronously");
|
||||
if (runAsynchronously is null)
|
||||
{
|
||||
if (context.ActivityDescriptor.Attributes.OfType<TaskActivityAttribute>().FirstOrDefault() is { } taskActivityAttribute)
|
||||
{
|
||||
runAsynchronously = taskActivityAttribute.RunAsynchronously;
|
||||
}
|
||||
else
|
||||
{
|
||||
runAsynchronously = false;
|
||||
}
|
||||
}
|
||||
|
||||
// 8) If composite, setup
|
||||
if (activity is IComposite composite)
|
||||
|
|
@ -197,4 +209,24 @@ public class ActivityFactory : IActivityFactory
|
|||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool? GetNullableBoolean(JsonElement element, string propertyName)
|
||||
{
|
||||
var propertyNames = new[] { propertyName.Camelize(), propertyName.Pascalize() };
|
||||
|
||||
foreach (var name in propertyNames)
|
||||
{
|
||||
if (element.TryGetProperty("customProperties", out var customPropertyElement))
|
||||
{
|
||||
if (customPropertyElement.TryGetProperty(name, out var canStartWorkflowElement))
|
||||
return (bool?)canStartWorkflowElement.GetValue();
|
||||
}
|
||||
|
||||
if (element.TryGetProperty(propertyName.Camelize(), out var property)
|
||||
&& (bool?)property.GetValue() is { } propValue)
|
||||
return propValue;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
using System.Text.Json;
|
||||
using Elsa.Extensions;
|
||||
using Elsa.Mediator.Contracts;
|
||||
using Elsa.Workflows.Attributes;
|
||||
using Elsa.Workflows.CommitStates;
|
||||
using Elsa.Workflows.Middleware.Activities;
|
||||
using Elsa.Workflows.Models;
|
||||
|
|
@ -103,7 +104,28 @@ public class BackgroundActivityInvokerMiddleware(
|
|||
|
||||
return !GetIsBackgroundExecution(context)
|
||||
&& context.WorkflowExecutionContext.ExecuteDelegate == null
|
||||
&& (kind is ActivityKind.Job || (kind == ActivityKind.Task && activity.GetRunAsynchronously()));
|
||||
&& (kind is ActivityKind.Job || GetTaskRunAsynchronously(context));
|
||||
}
|
||||
|
||||
private static bool GetTaskRunAsynchronously(ActivityExecutionContext context)
|
||||
{
|
||||
var activity = context.Activity;
|
||||
var activityDescriptor = context.ActivityDescriptor;
|
||||
var kind = activityDescriptor.Kind;
|
||||
|
||||
if (kind is not ActivityKind.Task)
|
||||
return false;
|
||||
|
||||
var runAsynchronously = activity.GetRunAsynchronously();
|
||||
|
||||
if (runAsynchronously is null)
|
||||
{
|
||||
var taskActivityAttribute = activityDescriptor.Attributes.OfType<TaskActivityAttribute>().FirstOrDefault();
|
||||
|
||||
return taskActivityAttribute is { RunAsynchronously: true };
|
||||
}
|
||||
|
||||
return (bool)runAsynchronously;
|
||||
}
|
||||
|
||||
private static bool GetIsBackgroundExecution(ActivityExecutionContext context) => context.TransientProperties.ContainsKey(BackgroundActivityExecutionContextExtensions.IsBackgroundExecution);
|
||||
|
|
|
|||
Loading…
Reference in a new issue