Change For/While/ForEach/IfElse behavior
Before this change, the aforementioned activities would always schedule the Done outcome. After this change, the Done outcome is scheduled **after** the Iterate branch and True or False branches have completed
This commit is contained in:
parent
997fb53b08
commit
fcfe7f08b4
|
|
@ -8,12 +8,12 @@ namespace Elsa.Activities.Console
|
|||
{
|
||||
public static class WriteLineBuilderExtensions
|
||||
{
|
||||
public static IOutcomeBuilder WriteLine(this IBuilder builder, Action<ISetupActivity<WriteLine>> setup, string? name = default, string? id = default) => WriteLine(builder.Then(setup).WithName(name).WithId(id));
|
||||
public static IOutcomeBuilder WriteLine(this IBuilder builder, Func<ActivityExecutionContext, string> text, string? name = default, string? id = default) => builder.WriteLine(activity => activity.Set(x => x.Text, text), name, id);
|
||||
public static IOutcomeBuilder WriteLine(this IBuilder builder, Func<ActivityExecutionContext, ValueTask<string>> text, string? name = default, string? id = default) => builder.WriteLine(activity => activity.Set(x => x.Text, text!), name, id);
|
||||
public static IOutcomeBuilder WriteLine(this IBuilder builder, Func<string> text, string? name = default, string? id = default) => builder.WriteLine(activity => activity.Set(x => x.Text, text), name, id);
|
||||
public static IOutcomeBuilder WriteLine(this IBuilder builder, Func<ValueTask<string>> text, string? name = default, string? id = default) => builder.WriteLine(activity => activity.Set(x => x.Text, text!), name, id);
|
||||
public static IOutcomeBuilder WriteLine(this IBuilder builder, string text, string? name = default, string? id = default) => builder.WriteLine(activity => activity.Set(x => x.Text, text), name, id);
|
||||
private static IOutcomeBuilder WriteLine(IActivityBuilder writeLine) => writeLine.When(OutcomeNames.Done);
|
||||
public static IActivityBuilder WriteLine(this IBuilder builder, Action<ISetupActivity<WriteLine>> setup) => builder.Then(setup);
|
||||
public static IActivityBuilder WriteLine(this IBuilder builder, Func<ActivityExecutionContext, string> text) => builder.WriteLine(activity => activity.WithText(text));
|
||||
public static IActivityBuilder WriteLine(this IBuilder builder, Func<ActivityExecutionContext, ValueTask<string>> text) => builder.WriteLine(activity => activity.WithText(text!));
|
||||
public static IActivityBuilder WriteLine(this IBuilder builder, Func<string> text) => builder.WriteLine(activity => activity.WithText(text!));
|
||||
public static IActivityBuilder WriteLine(this IBuilder builder, Func<ValueTask<string>> text) => builder.WriteLine(activity => activity.WithText(text!));
|
||||
public static IActivityBuilder WriteLine(this IBuilder builder, string text) => builder.WriteLine(activity => activity.WithText(text!));
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -25,16 +25,40 @@ namespace Elsa.ActivityResults
|
|||
{
|
||||
var outcomes = activityExecutionContext.Outcomes = Outcomes.ToList();
|
||||
var workflowExecutionContext = activityExecutionContext.WorkflowExecutionContext;
|
||||
var nextConnections = GetNextConnections(workflowExecutionContext, activityExecutionContext.ActivityBlueprint.Id, outcomes).ToList();
|
||||
|
||||
var nextActivities = GetNextActivities(
|
||||
workflowExecutionContext,
|
||||
activityExecutionContext.ActivityBlueprint.Id,
|
||||
outcomes).ToList();
|
||||
var nextActivities =
|
||||
(
|
||||
from connection in nextConnections
|
||||
from activityBlueprint in workflowExecutionContext.WorkflowBlueprint.Activities
|
||||
where activityBlueprint.Id == connection.Target.Activity.Id
|
||||
select activityBlueprint.Id
|
||||
)
|
||||
.Distinct();
|
||||
|
||||
workflowExecutionContext.ScheduleActivities(nextActivities, activityExecutionContext.Output);
|
||||
foreach (var nextConnection in nextConnections)
|
||||
workflowExecutionContext.ExecutionLog.Add(nextConnection);
|
||||
|
||||
workflowExecutionContext.ScheduleActivities(nextActivities, activityExecutionContext.Output);
|
||||
}
|
||||
|
||||
private IEnumerable<string> GetNextActivities(
|
||||
public static IEnumerable<string> GetNextActivities(
|
||||
WorkflowExecutionContext workflowContext,
|
||||
string sourceId,
|
||||
IEnumerable<string> outcomes)
|
||||
{
|
||||
var nextConnections = GetNextConnections(workflowContext, sourceId, outcomes);
|
||||
|
||||
var query =
|
||||
from connection in nextConnections
|
||||
from activityBlueprint in workflowContext.WorkflowBlueprint.Activities
|
||||
where activityBlueprint.Id == connection.Target.Activity.Id
|
||||
select activityBlueprint.Id;
|
||||
|
||||
return query.Distinct();
|
||||
}
|
||||
|
||||
public static IEnumerable<IConnection> GetNextConnections(
|
||||
WorkflowExecutionContext workflowContext,
|
||||
string sourceId,
|
||||
IEnumerable<string> outcomes)
|
||||
|
|
@ -47,12 +71,10 @@ namespace Elsa.ActivityResults
|
|||
let connectionOutcome = connection.Source.Outcome ?? OutcomeNames.Done
|
||||
let isConnectionOutcome = connectionOutcome.Equals(outcome.outcome, StringComparison.OrdinalIgnoreCase)
|
||||
where connection.Source.Activity.Id == sourceId && isConnectionOutcome
|
||||
from activityBlueprint in workflowContext.WorkflowBlueprint.Activities
|
||||
where activityBlueprint.Id == connection.Target.Activity.Id
|
||||
orderby outcome.order
|
||||
select activityBlueprint.Id;
|
||||
select connection;
|
||||
|
||||
return query.Distinct();
|
||||
return query;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Elsa.Services;
|
||||
using Elsa.Services.Models;
|
||||
|
||||
namespace Elsa.Builders
|
||||
{
|
||||
|
|
@ -28,5 +29,6 @@ namespace Elsa.Builders
|
|||
IActivityBuilder LoadWorkflowContext(bool value = true);
|
||||
IActivityBuilder SaveWorkflowContext(bool value = true);
|
||||
IActivityBuilder PersistWorkflow(bool value = true);
|
||||
IWorkflowBlueprint Build();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
namespace Elsa.Services.Models
|
||||
{
|
||||
public interface IBranchingActivity
|
||||
{
|
||||
void Unwind(ActivityExecutionContext context);
|
||||
}
|
||||
}
|
||||
|
|
@ -67,7 +67,7 @@ namespace Elsa.Services.Models
|
|||
}
|
||||
|
||||
public bool DeleteCompletedInstances => WorkflowBlueprint.DeleteCompletedInstances;
|
||||
public ICollection<string> ExecutionLog => new List<string>();
|
||||
public IList<IConnection> ExecutionLog { get; } = new List<IConnection>();
|
||||
public WorkflowStatus Status => WorkflowInstance.WorkflowStatus;
|
||||
public bool HasBlockingActivities => WorkflowInstance.BlockingActivities.Any();
|
||||
public object? WorkflowContext { get; set; }
|
||||
|
|
@ -135,12 +135,6 @@ namespace Elsa.Services.Models
|
|||
public void SetWorkflowContext(object? value) => WorkflowContext = value;
|
||||
public T GetWorkflowContext<T>() => (T) WorkflowContext!;
|
||||
|
||||
public async ValueTask<IEnumerable<RuntimeActivityInstance>> ActivateActivitiesAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
var activityExecutionContexts = WorkflowBlueprint.Activities.Select(x => new ActivityExecutionContext(ServiceScope, this, x, null, CancellationToken.None));
|
||||
return await Task.WhenAll(activityExecutionContexts.Select(async x => await x.ActivateActivityAsync(cancellationToken)));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove empty activity data to save on document size.
|
||||
/// </summary>
|
||||
|
|
@ -156,4 +150,6 @@ namespace Elsa.Services.Models
|
|||
return activityBlueprint != null && activityBlueprint.PersistOutput;
|
||||
}
|
||||
}
|
||||
|
||||
public record ExecutionLogEntry(string ActivityId, string Outcome);
|
||||
}
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
using System;
|
||||
using Elsa.ActivityResults;
|
||||
using Elsa.Attributes;
|
||||
using Elsa.Services;
|
||||
using Elsa.Services.Models;
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
|
|
@ -12,7 +11,7 @@ namespace Elsa.Activities.ControlFlow
|
|||
Description = "Iterate between two numbers.",
|
||||
Outcomes = new[] { OutcomeNames.Iterate, OutcomeNames.Done }
|
||||
)]
|
||||
public class For : Activity
|
||||
public class For : IteratingActivity
|
||||
{
|
||||
[ActivityProperty(Hint = "An expression that evaluates to the starting number.")]
|
||||
public long Start { get; set; }
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ namespace Elsa.Activities.ControlFlow
|
|||
Description = "Iterate over a collection.",
|
||||
Outcomes = new[] { OutcomeNames.Iterate, OutcomeNames.Done }
|
||||
)]
|
||||
public class ForEach : Activity
|
||||
public class ForEach : IteratingActivity
|
||||
{
|
||||
[ActivityProperty(Hint = "Enter an expression that evaluates to a collection of items to iterate over.")]
|
||||
public ICollection<object> Items { get; set; } = new Collection<object>();
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Elsa.ActivityResults;
|
||||
using Elsa.Attributes;
|
||||
using Elsa.Services;
|
||||
|
|
@ -12,7 +14,7 @@ namespace Elsa.Activities.ControlFlow
|
|||
Description = "Evaluate a Boolean expression and continue execution depending on the result.",
|
||||
Outcomes = new[] { True, False, OutcomeNames.Done }
|
||||
)]
|
||||
public class IfElse : Activity
|
||||
public class IfElse : Activity, IBranchingActivity
|
||||
{
|
||||
public const string True = "True";
|
||||
public const string False = "False";
|
||||
|
|
@ -23,7 +25,47 @@ namespace Elsa.Activities.ControlFlow
|
|||
protected override IActivityExecutionResult OnExecute(ActivityExecutionContext context)
|
||||
{
|
||||
var outcome = Condition ? True : False;
|
||||
return Outcomes(OutcomeNames.Done, outcome);
|
||||
return Outcome(outcome);
|
||||
}
|
||||
|
||||
public void Unwind(ActivityExecutionContext context)
|
||||
{
|
||||
var workflowExecutionContext = context.WorkflowExecutionContext;
|
||||
var workflowBlueprint = workflowExecutionContext.WorkflowBlueprint;
|
||||
var activityExecutionContext = context;
|
||||
var currentActivityBlueprint = activityExecutionContext.ActivityBlueprint;
|
||||
var currentActivityId = currentActivityBlueprint.Id;
|
||||
|
||||
// An IfElse activity completed within a burst of execution, which means its outcome (true or false) did not yield child activities to execute (an empty branch).
|
||||
// Schedule its child activities connected to the "Done" outcome.
|
||||
if (currentActivityBlueprint.Type == nameof(IfElse))
|
||||
{
|
||||
var nextActivities = GetNextActivities(workflowExecutionContext, currentActivityId);
|
||||
workflowExecutionContext.ScheduleActivities(nextActivities);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Get all incoming connections.
|
||||
var inboundConnections = workflowBlueprint.GetInboundConnectionPath(currentActivityId).ToList();
|
||||
|
||||
// Filter out those connections who have a source of IfElse.
|
||||
var query =
|
||||
from inboundConnection in inboundConnections
|
||||
let parentActivityBlueprint = inboundConnection.Source.Activity
|
||||
where inboundConnection.Source.Activity.Type == nameof(IfElse)
|
||||
select inboundConnection;
|
||||
|
||||
var firstMatch = query.FirstOrDefault();
|
||||
|
||||
if (firstMatch != null && firstMatch.Source.Outcome != OutcomeNames.Done)
|
||||
{
|
||||
var parentActivityBlueprint = firstMatch.Source.Activity;
|
||||
var nextActivities = OutcomeResult.GetNextActivities(workflowExecutionContext, parentActivityBlueprint.Id, new[] { OutcomeNames.Done }).ToList();
|
||||
workflowExecutionContext.ScheduleActivities(nextActivities);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerable<string> GetNextActivities(WorkflowExecutionContext workflowExecutionContext, string currentActivityId) => OutcomeResult.GetNextActivities(workflowExecutionContext, currentActivityId, new[] { OutcomeNames.Done });
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
using System.Linq;
|
||||
using Elsa.Services;
|
||||
using Elsa.Services.Models;
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
namespace Elsa.Activities.ControlFlow
|
||||
{
|
||||
public abstract class IteratingActivity : Activity, IBranchingActivity
|
||||
{
|
||||
public void Unwind(ActivityExecutionContext context)
|
||||
{
|
||||
var workflowExecutionContext = context.WorkflowExecutionContext;
|
||||
var workflowBlueprint = workflowExecutionContext.WorkflowBlueprint;
|
||||
var currentActivityId = context.ActivityBlueprint.Id;
|
||||
var inboundConnections = workflowBlueprint.GetInboundConnectionPath(currentActivityId).ToList();
|
||||
|
||||
var query =
|
||||
from inboundConnection in inboundConnections
|
||||
let parentActivityBlueprint = inboundConnection.Source.Activity
|
||||
where inboundConnection.Source.Activity.Type == Type
|
||||
select inboundConnection;
|
||||
|
||||
var firstMatch = query.FirstOrDefault();
|
||||
|
||||
if(firstMatch != null && firstMatch.Source.Outcome == OutcomeNames.Iterate)
|
||||
workflowExecutionContext.ScheduleActivity(firstMatch.Source.Activity.Id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -22,11 +22,25 @@ namespace Elsa.Activities.ControlFlow
|
|||
[ActivityProperty(Hint = "The conditions to evaluate.")]
|
||||
public SwitchMode Mode { get; set; } = SwitchMode.MatchFirst;
|
||||
|
||||
private bool Evaluated
|
||||
{
|
||||
get => GetState<bool>();
|
||||
set => SetState(value);
|
||||
}
|
||||
|
||||
protected override IActivityExecutionResult OnExecute(ActivityExecutionContext context)
|
||||
{
|
||||
if (Evaluated)
|
||||
{
|
||||
Evaluated = false;
|
||||
return Done();
|
||||
}
|
||||
|
||||
var matches = Cases.Where(x => x.Condition).Select(x => x.Name).ToList();
|
||||
var results = Mode == SwitchMode.MatchFirst ? matches.Any() ? new[] { matches.First() } : new string[0] : matches.ToArray();
|
||||
var outcomes = new[] { OutcomeNames.Done }.Concat(results);
|
||||
|
||||
Evaluated = true;
|
||||
return Outcomes(outcomes);
|
||||
}
|
||||
}
|
||||
|
|
@ -11,7 +11,7 @@ namespace Elsa.Activities.ControlFlow
|
|||
Description = "Execute while a given condition is true.",
|
||||
Outcomes = new[] { OutcomeNames.Iterate, OutcomeNames.Done }
|
||||
)]
|
||||
public class While : Activity
|
||||
public class While : IteratingActivity
|
||||
{
|
||||
[ActivityProperty(Hint = "The condition to evaluate.")]
|
||||
public bool Condition { get; set; }
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ namespace Elsa.ActivityResults
|
|||
if (previousEntry == null)
|
||||
return;
|
||||
|
||||
var activityId = previousEntry;
|
||||
var activityId = previousEntry.Source.Activity.Id;
|
||||
workflowExecutionContext.ScheduleActivity(activityId, _input);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Elsa.Services;
|
||||
using Elsa.Services.Models;
|
||||
|
||||
namespace Elsa.Builders
|
||||
{
|
||||
|
|
@ -108,5 +109,7 @@ namespace Elsa.Builders
|
|||
PersistWorkflowEnabled = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
public IWorkflowBlueprint Build() => ((IWorkflowBuilder)WorkflowBuilder).BuildBlueprint();
|
||||
}
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@
|
|||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=activities_005Ccontrolflow_005Cfinish/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=activities_005Ccontrolflow_005Cfor/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=activities_005Ccontrolflow_005Cifthen/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=activities_005Ccontrolflow_005Cswitch/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=activities_005Cprimitives_005Csetname/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=activities_005Csignaling_005Cactivities_005Creceivesignal/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=activities_005Csignaling_005Cactivities_005Csignalreceived/@EntryIndexedValue">True</s:Boolean>
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ using Elsa.Runtime;
|
|||
using Elsa.Serialization;
|
||||
using Elsa.Serialization.Converters;
|
||||
using Elsa.Services;
|
||||
using Elsa.Services.Models;
|
||||
using Elsa.StartupTasks;
|
||||
using Elsa.Triggers;
|
||||
using Elsa.WorkflowProviders;
|
||||
|
|
@ -54,6 +55,11 @@ namespace Microsoft.Extensions.DependencyInjection
|
|||
.AddSingleton(options.StorageFactory)
|
||||
.AddStartupTask<CreateSubscriptions>();
|
||||
|
||||
services
|
||||
.AddTransient<IBranchingActivity, IfElse>()
|
||||
.AddTransient<IBranchingActivity, For>()
|
||||
.AddTransient<IBranchingActivity, While>();
|
||||
|
||||
options
|
||||
.AddWorkflowsCore()
|
||||
.AddCoreActivities();
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Elsa.Events;
|
||||
|
|
@ -12,37 +12,30 @@ namespace Elsa.Handlers
|
|||
/// Walks up the tee of inbound connections along the "Iterate" outcome of the looping construct (While/For/ForEach) and re-schedules the looping activity.
|
||||
/// Also handles composite activity re-scheduling.
|
||||
/// </summary>
|
||||
public class RescheduleLoopsAndContainers : INotificationHandler<WorkflowExecutionBurstCompleted>
|
||||
public class RescheduleBranchingActivitiesAndContainers : INotificationHandler<WorkflowExecutionBurstCompleted>
|
||||
{
|
||||
public Task Handle(WorkflowExecutionBurstCompleted notification, CancellationToken cancellationToken)
|
||||
private readonly IEnumerable<IBranchingActivity> _branchingActivities;
|
||||
|
||||
public RescheduleBranchingActivitiesAndContainers(IEnumerable<IBranchingActivity> branchingActivities)
|
||||
{
|
||||
ScheduleLoops(notification);
|
||||
ScheduleContainers(notification);
|
||||
return Task.CompletedTask;
|
||||
_branchingActivities = branchingActivities;
|
||||
}
|
||||
|
||||
private static void ScheduleLoops(WorkflowExecutionBurstCompleted notification)
|
||||
public Task Handle(WorkflowExecutionBurstCompleted notification, CancellationToken cancellationToken)
|
||||
{
|
||||
var workflowExecutionContext = notification.WorkflowExecutionContext;
|
||||
var activityExecutionContext = notification.ActivityExecutionContext;
|
||||
|
||||
// If no suspension has been instructed, re-schedule any post-scheduled activities.
|
||||
if (workflowExecutionContext.HasScheduledActivities || workflowExecutionContext.Status != WorkflowStatus.Running)
|
||||
return;
|
||||
foreach (var branchingActivity in _branchingActivities)
|
||||
{
|
||||
if (workflowExecutionContext.HasScheduledActivities || workflowExecutionContext.Status != WorkflowStatus.Running)
|
||||
break;
|
||||
|
||||
var workflowBlueprint = workflowExecutionContext.WorkflowBlueprint;
|
||||
var currentActivityId = notification.ActivityExecutionContext.ActivityBlueprint.Id;
|
||||
var inboundConnections = workflowBlueprint.GetInboundConnectionPath(currentActivityId).ToList();
|
||||
branchingActivity.Unwind(activityExecutionContext);
|
||||
}
|
||||
|
||||
var query =
|
||||
from inboundConnection in inboundConnections
|
||||
let parentActivityBlueprint = inboundConnection.Source.Activity
|
||||
where inboundConnection.Source.Outcome == OutcomeNames.Iterate
|
||||
select parentActivityBlueprint;
|
||||
|
||||
var firstLoop = query.FirstOrDefault();
|
||||
|
||||
if(firstLoop != null)
|
||||
workflowExecutionContext.ScheduleActivity(firstLoop.Id);
|
||||
ScheduleContainers(notification);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private static void ScheduleContainers(WorkflowExecutionBurstCompleted notification)
|
||||
|
|
@ -18,6 +18,7 @@ namespace Elsa.Services
|
|||
var activity = _elsaOptions.ActivityFactory.CreateService(type, context.ServiceScope.ServiceProvider);
|
||||
activity.Data = context.GetData();
|
||||
activity.Id = context.ActivityId;
|
||||
|
||||
await context.WorkflowExecutionContext.WorkflowBlueprint.ActivityPropertyProviders.SetActivityPropertiesAsync(activity, context, context.CancellationToken);
|
||||
return activity;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -290,7 +290,6 @@ namespace Elsa.Services
|
|||
await _mediator.Publish(new ActivityExecuted(activityExecutionContext), cancellationToken);
|
||||
await result.ExecuteAsync(activityExecutionContext, cancellationToken);
|
||||
workflowExecutionContext.WorkflowInstance.Output = activityExecutionContext.Output;
|
||||
workflowExecutionContext.ExecutionLog.Add(activity.Id);
|
||||
workflowExecutionContext.PruneActivityData();
|
||||
activityOperation = Execute;
|
||||
workflowExecutionContext.CompletePass();
|
||||
|
|
|
|||
|
|
@ -146,7 +146,7 @@ namespace Elsa.Triggers
|
|||
|
||||
if (workflowInstanceId != null)
|
||||
{
|
||||
descriptors = _descriptors![workflowBlueprint.Id].ToList();
|
||||
descriptors = _descriptors!.ContainsKey(workflowBlueprint.Id) ? _descriptors[workflowBlueprint.Id].ToList() : new List<TriggerDescriptor>();
|
||||
descriptors.RemoveAll(x => x.WorkflowInstanceId == workflowInstanceId);
|
||||
|
||||
var workflowInstance = await _workflowInstanceStore.FindByIdAsync(workflowInstanceId, cancellationToken);
|
||||
|
|
|
|||
|
|
@ -17,23 +17,24 @@ namespace Elsa.Samples.IfElseConsole
|
|||
public void Build(IWorkflowBuilder workflow)
|
||||
{
|
||||
workflow
|
||||
.WriteLine("--POND OF HAPPINESS--", "Start")
|
||||
.WriteLine("--POND OF HAPPINESS--")
|
||||
.WriteLine("Throw some Rupees in and your wishes will surely come true.")
|
||||
.WriteLine("Do you want to throw Rupees?")
|
||||
.WriteLine("Do you want to throw Rupees?").WithName("Start")
|
||||
.ReadLine()
|
||||
.IfElse(context => IsYes(context.Input),
|
||||
ifElse =>
|
||||
{
|
||||
ifElse
|
||||
.When(IfElse.True)
|
||||
.When(OutcomeNames.True)
|
||||
.WriteLine(GetCurse)
|
||||
.WriteLine("...")
|
||||
.Then("Start");
|
||||
|
||||
ifElse
|
||||
.When(IfElse.False)
|
||||
.WriteLine("Bye.");
|
||||
});
|
||||
.When(OutcomeNames.False)
|
||||
.WriteLine("Keep your rupees.");
|
||||
})
|
||||
.WriteLine("--END--");
|
||||
}
|
||||
|
||||
private static bool IsYes(object? value)
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ namespace Elsa.Samples.SwitchConsole
|
|||
public void Build(IWorkflowBuilder workflow)
|
||||
{
|
||||
workflow
|
||||
.WriteLine("--Grayscale Calculator--", "Start")
|
||||
.WriteLine("--Grayscale Calculator--").WithName("Start")
|
||||
.WriteLine("Enter a number between 0 and 100.")
|
||||
.ReadLine()
|
||||
.Switch(cases =>
|
||||
|
|
|
|||
|
|
@ -20,12 +20,12 @@ namespace Elsa.Core.IntegrationTests.Workflows
|
|||
activity => activity.Set(x => x.Branches, new HashSet<string>(new[] { "Branch 1", "Branch 2", "Branch 3" })),
|
||||
fork =>
|
||||
{
|
||||
fork.When("Branch 1").SignalReceived("Signal1").WriteLine("Branch 1 executed", "WriteLine1").Then("Join");
|
||||
fork.When("Branch 2").SignalReceived("Signal2").WriteLine("Branch 2 executed", "WriteLine2").Then("Join");
|
||||
fork.When("Branch 3").SignalReceived("Signal3").WriteLine("Branch 3 executed", "WriteLine3").Then("Join");
|
||||
fork.When("Branch 1").SignalReceived("Signal1").WriteLine("Branch 1 executed").WithName("WriteLine1").Then("Join");
|
||||
fork.When("Branch 2").SignalReceived("Signal2").WriteLine("Branch 2 executed").WithName("WriteLine2").Then("Join");
|
||||
fork.When("Branch 3").SignalReceived("Signal3").WriteLine("Branch 3 executed").WithName("WriteLine3").Then("Join");
|
||||
})
|
||||
.Add<Join>(join => join.Set(x => x.Mode, _joinMode)).WithName("Join")
|
||||
.WriteLine("Finished", "Finished");
|
||||
.WriteLine("Finished").WithName("Finished");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -25,7 +25,7 @@ namespace Elsa.Core.IntegrationTests.Workflows
|
|||
{
|
||||
@while
|
||||
.When(OutcomeNames.Iterate)
|
||||
.WriteLine(context => $"Inside while loop. Counter = {context.GetVariable<int>(CounterVariableName)}", id: "WriteLoopCount")
|
||||
.WriteLine(context => $"Inside while loop. Counter = {context.GetVariable<int>(CounterVariableName)}").WithId("WriteLoopCount")
|
||||
.SetVariable(CounterVariableName, context => GetCounter(context) + 1);
|
||||
|
||||
})
|
||||
|
|
|
|||
Loading…
Reference in a new issue