From b6641606364b06dab3054adfd86d7734eceeb227 Mon Sep 17 00:00:00 2001 From: iio888 <102009054+iio888@users.noreply.github.com> Date: Wed, 14 Aug 2024 15:18:04 +0800 Subject: [PATCH 01/17] Update End.cs Send BreakSignal when executing End Activity --- src/modules/Elsa.Workflows.Core/Activities/End.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/modules/Elsa.Workflows.Core/Activities/End.cs b/src/modules/Elsa.Workflows.Core/Activities/End.cs index 559564904b..f8e6e80784 100644 --- a/src/modules/Elsa.Workflows.Core/Activities/End.cs +++ b/src/modules/Elsa.Workflows.Core/Activities/End.cs @@ -16,4 +16,9 @@ public class End : CodeActivity, ITerminalNode public End([CallerFilePath] string? source = default, [CallerLineNumber] int? line = default) : base(source, line) { } -} \ No newline at end of file + + protected async override ValueTask ExecuteAsync(ActivityExecutionContext context) + { + await context.SendSignalAsync(new BreakSignal()); + } +} From c8781b4d6a307169bd48ae71f1118155ea12ffad Mon Sep 17 00:00:00 2001 From: iio888 <102009054+iio888@users.noreply.github.com> Date: Wed, 14 Aug 2024 15:21:59 +0800 Subject: [PATCH 02/17] Update Flowchart.cs Check isBreaking when a child completed in Flowchart --- .../Activities/Flowchart/Activities/Flowchart.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/modules/Elsa.Workflows.Core/Activities/Flowchart/Activities/Flowchart.cs b/src/modules/Elsa.Workflows.Core/Activities/Flowchart/Activities/Flowchart.cs index 96cd4b7183..02e8e5f361 100644 --- a/src/modules/Elsa.Workflows.Core/Activities/Flowchart/Activities/Flowchart.cs +++ b/src/modules/Elsa.Workflows.Core/Activities/Flowchart/Activities/Flowchart.cs @@ -144,6 +144,12 @@ private async ValueTask OnChildCompletedAsync(ActivityCompletedContext context) var completedActivity = completedActivityContext.Activity; var result = context.Result; + bool isBreaking = flowchartContext.GetIsBreaking(); + if (isBreaking) { + await flowchartContext.CompleteActivityAsync(); + return; + } + // If the complete activity's status is anything but "Completed", do not schedule its outbound activities. var scheduleChildren = completedActivityContext.Status == ActivityStatus.Completed; var outcomeNames = result is Outcomes outcomes @@ -286,4 +292,4 @@ private async ValueTask OnActivityCanceledAsync(CancelSignal signal, SignalConte { await CompleteIfNoPendingWorkAsync(context.ReceiverActivityExecutionContext); } -} \ No newline at end of file +} From 489ed12a9549278650496cb0ebc0832a69c7a632 Mon Sep 17 00:00:00 2001 From: iio888 <102009054+iio888@users.noreply.github.com> Date: Wed, 14 Aug 2024 15:36:10 +0800 Subject: [PATCH 03/17] Create BreakWhileFlowchartWorkflow.cs --- .../Workflows/BreakWhileFlowchartWorkflow.cs | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 test/integration/Elsa.Workflows.IntegrationTests/Activities/Break/Workflows/BreakWhileFlowchartWorkflow.cs diff --git a/test/integration/Elsa.Workflows.IntegrationTests/Activities/Break/Workflows/BreakWhileFlowchartWorkflow.cs b/test/integration/Elsa.Workflows.IntegrationTests/Activities/Break/Workflows/BreakWhileFlowchartWorkflow.cs new file mode 100644 index 0000000000..2febb911a3 --- /dev/null +++ b/test/integration/Elsa.Workflows.IntegrationTests/Activities/Break/Workflows/BreakWhileFlowchartWorkflow.cs @@ -0,0 +1,31 @@ +using Elsa.Workflows.Activities.Flowchart.Models; +using Elsa.Workflows.Activities; +using Elsa.Workflows.Activities.Flowchart.Activities; +using Elsa.Workflows.Contracts; + +namespaces Elsa.Workflows.IntegrationTests.Activities.Workflows; +public class BreakWhileFlowchart : WorkflowBase +{ + protected override void Build(IWorkflowBuilder workflow) + { + WtiteLine start = new("start"); + WriteLine end = new("end"); + If condition = new If(c => true) + { + Then = new Break() + }; + + workflow.Root = While.True(new Flowchart() + { + Activities = + { + start, condition, end + }, + Connections = + { + new Connection(start, condition), + new Connection(condition, end), + } + }); + } +} From 93c3417f2a68f703afcc072378dea83f905d1632 Mon Sep 17 00:00:00 2001 From: iio888 <102009054+iio888@users.noreply.github.com> Date: Wed, 14 Aug 2024 15:40:10 +0800 Subject: [PATCH 04/17] Update BreakTests.cs Add test case of Breaking from a While which includes a Flowchart --- .../Activities/Break/BreakTests.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/test/integration/Elsa.Workflows.IntegrationTests/Activities/Break/BreakTests.cs b/test/integration/Elsa.Workflows.IntegrationTests/Activities/Break/BreakTests.cs index 9d55ded6b6..9109899309 100644 --- a/test/integration/Elsa.Workflows.IntegrationTests/Activities/Break/BreakTests.cs +++ b/test/integration/Elsa.Workflows.IntegrationTests/Activities/Break/BreakTests.cs @@ -62,4 +62,13 @@ public async Task Test5() var lines = _capturingTextWriter.Lines.ToList(); Assert.Equal(new[] { "Start", "1", "2", "End" }, lines); } -} \ No newline at end of file + + [Fact(DisplayName = "Break While whin a Flowchart")] + public async Task Test6() + { + await _services.PopulateRegistriesAsync(); + await _workflowRunner.RunAsync(); + var lines = _capturingTextWriter.Lines.ToList(); + Assert.Equal(new[] { "start" }, lines); + } +} From 5eaf2dc46cb4e8af90993d226c4618ea922f6ef9 Mon Sep 17 00:00:00 2001 From: iio888 <102009054+iio888@users.noreply.github.com> Date: Wed, 14 Aug 2024 15:47:52 +0800 Subject: [PATCH 05/17] Create EndFlowchartWorkflow.cs Add test case of ending a flowchart when the end activity is nested in a If. --- .../Activities/End/EndFlowchartWorkflow.cs | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 test/integration/Elsa.Workflows.IntegrationTests/Activities/End/EndFlowchartWorkflow.cs diff --git a/test/integration/Elsa.Workflows.IntegrationTests/Activities/End/EndFlowchartWorkflow.cs b/test/integration/Elsa.Workflows.IntegrationTests/Activities/End/EndFlowchartWorkflow.cs new file mode 100644 index 0000000000..0ab4c57a89 --- /dev/null +++ b/test/integration/Elsa.Workflows.IntegrationTests/Activities/End/EndFlowchartWorkflow.cs @@ -0,0 +1,29 @@ +using Elsa.Workflows.Activities.Flowchart.Models; +using Elsa.Workflows.Activities; +using Elsa.Workflows.Activities.Flowchart.Activities; +using Elsa.Workflows.Contracts; + +namespace Elsa.Workflows.IntegrationTests.Activities.Workflows; +public class EndFlowchartWorkflow : WorkflowBase +{ + protected override void Build(IWorkflowBuilder workflow) + { + WriteLine start = new("start"); + WriteLine end = new("end"); + If condition = new(c => true) + { + Then = new End() + }; + + workflow.Root = new Flowchart() + { + Activities = { + start, condition, end + }, + Connections = { + new Connection(start, condition), + new Connection(condition, end), + } + }; + } +} From 62d234542dbc4d98b67e481c8799d20bc7bfaae2 Mon Sep 17 00:00:00 2001 From: iio888 <102009054+iio888@users.noreply.github.com> Date: Wed, 14 Aug 2024 15:57:38 +0800 Subject: [PATCH 06/17] Create EndTests.cs Add test case --- .../Activities/End/EndTests.cs | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 test/integration/Elsa.Workflows.IntegrationTests/Activities/End/EndTests.cs diff --git a/test/integration/Elsa.Workflows.IntegrationTests/Activities/End/EndTests.cs b/test/integration/Elsa.Workflows.IntegrationTests/Activities/End/EndTests.cs new file mode 100644 index 0000000000..91f8e86a54 --- /dev/null +++ b/test/integration/Elsa.Workflows.IntegrationTests/Activities/End/EndTests.cs @@ -0,0 +1,29 @@ +using Elsa.Testing.Shared; +using Elsa.Workflows.Contracts; +using Elsa.Workflows.IntegrationTests.Activities.Workflows; +using Microsoft.Extensions.DependencyInjection; +using Xunit; +using Xunit.Abstraction; + +namespace Elsa.Workflows.IntegrationTests,Activities; +public class EndTests +{ + private readonly IWorkflowRunner _workflowRunner; + private readonly CapturingTextWriter _capturingTextWriter = new(); + private readonly IServiceProvider _services; + + public EndTests(ITestOutputHelper testOutputHelper) + { + _services = new TestApplicationBuilder(testOutputHelper).WithCapturingTextWriter(_capturingTextWriter).Build(); + _workflowRunner = _services.GetRequiredService(); + } + + [Fact(DisplayName = "End a flowchart when the End is nested in If")] + public async Task Test1() + { + await _services.PopulateRegistriesAsync(); + await _workflowRunner.RunAsync(); + var lines = _capturingTextWriter.Lines.ToList(); + Assert.Equal(new[] { "start" }, lines); + } +} From 8f853b2f6c0e374e5614187348f190df4190770b Mon Sep 17 00:00:00 2001 From: iio888 <102009054+iio888@users.noreply.github.com> Date: Thu, 15 Aug 2024 15:53:38 +0800 Subject: [PATCH 07/17] Clean Flowchart.cs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit , --- .../Activities/Flowchart/Activities/Flowchart.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/modules/Elsa.Workflows.Core/Activities/Flowchart/Activities/Flowchart.cs b/src/modules/Elsa.Workflows.Core/Activities/Flowchart/Activities/Flowchart.cs index 02e8e5f361..3b33b8265b 100644 --- a/src/modules/Elsa.Workflows.Core/Activities/Flowchart/Activities/Flowchart.cs +++ b/src/modules/Elsa.Workflows.Core/Activities/Flowchart/Activities/Flowchart.cs @@ -145,7 +145,8 @@ private async ValueTask OnChildCompletedAsync(ActivityCompletedContext context) var result = context.Result; bool isBreaking = flowchartContext.GetIsBreaking(); - if (isBreaking) { + if (isBreaking) + { await flowchartContext.CompleteActivityAsync(); return; } From 36ebf0de3728c782cb79af7e90074b8fdc089094 Mon Sep 17 00:00:00 2001 From: iio888 <102009054+iio888@users.noreply.github.com> Date: Sat, 17 Aug 2024 15:25:56 +0800 Subject: [PATCH 08/17] Create EndSignal.cs --- src/modules/Elsa.Workflows.Core/Signals/EndSignal.cs | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 src/modules/Elsa.Workflows.Core/Signals/EndSignal.cs diff --git a/src/modules/Elsa.Workflows.Core/Signals/EndSignal.cs b/src/modules/Elsa.Workflows.Core/Signals/EndSignal.cs new file mode 100644 index 0000000000..c45a4a6a40 --- /dev/null +++ b/src/modules/Elsa.Workflows.Core/Signals/EndSignal.cs @@ -0,0 +1,3 @@ +namespaces Elsa.Workflows.Signals; + +public record EndSignal; From b461cc1d7a899f69ec32d9730e667a499c0560b2 Mon Sep 17 00:00:00 2001 From: iio888 <102009054+iio888@users.noreply.github.com> Date: Sat, 17 Aug 2024 15:28:02 +0800 Subject: [PATCH 09/17] Send EndSignal in End --- src/modules/Elsa.Workflows.Core/Activities/End.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/Elsa.Workflows.Core/Activities/End.cs b/src/modules/Elsa.Workflows.Core/Activities/End.cs index f8e6e80784..a574a66910 100644 --- a/src/modules/Elsa.Workflows.Core/Activities/End.cs +++ b/src/modules/Elsa.Workflows.Core/Activities/End.cs @@ -19,6 +19,6 @@ public End([CallerFilePath] string? source = default, [CallerLineNumber] int? li protected async override ValueTask ExecuteAsync(ActivityExecutionContext context) { - await context.SendSignalAsync(new BreakSignal()); + await context.SendSignalAsync(new EndSignal()); } } From 7d4fd32b793bcdd19c7fe88da264094a3a5ca246 Mon Sep 17 00:00:00 2001 From: iio888 <102009054+iio888@users.noreply.github.com> Date: Sat, 17 Aug 2024 15:59:48 +0800 Subject: [PATCH 10/17] Create EndSignalActivityExecutionContextExtensions.cs --- .../EndSignalActivityExecutionContextExtensions.cs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 src/modules/Elsa.Workflows.Core/Extensions/EndSignalActivityExecutionContextExtensions.cs diff --git a/src/modules/Elsa.Workflows.Core/Extensions/EndSignalActivityExecutionContextExtensions.cs b/src/modules/Elsa.Workflows.Core/Extensions/EndSignalActivityExecutionContextExtensions.cs new file mode 100644 index 0000000000..c6302bf56d --- /dev/null +++ b/src/modules/Elsa.Workflows.Core/Extensions/EndSignalActivityExecutionContextExtensions.cs @@ -0,0 +1,14 @@ +namespace Elsa.Workflows.Extensions; + +public static class EndSignalActivityExecutionContextExtensions +{ + /// + /// Gets a value indicating whether the current activity is ending out of a flowchart. + /// + public static bool GetIsEnding(this ActivityExecutionContext context) => context.GetProperty("IsEnding"); + + /// + /// Sets a value indicating whether the current activity is ending out of a flowchart. + /// + public static void SetIsEnding(this ActivityExecutionContext context) => context.SetProperty("IsEnding", true); +} From c599a955dd3b0aed5a054b4af606b53b6c010236 Mon Sep 17 00:00:00 2001 From: iio888 <102009054+iio888@users.noreply.github.com> Date: Sat, 17 Aug 2024 16:21:11 +0800 Subject: [PATCH 11/17] Change BreakSignal to EndSignal --- .../Activities/Flowchart/Activities/Flowchart.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/modules/Elsa.Workflows.Core/Activities/Flowchart/Activities/Flowchart.cs b/src/modules/Elsa.Workflows.Core/Activities/Flowchart/Activities/Flowchart.cs index 3b33b8265b..ddd551e6ad 100644 --- a/src/modules/Elsa.Workflows.Core/Activities/Flowchart/Activities/Flowchart.cs +++ b/src/modules/Elsa.Workflows.Core/Activities/Flowchart/Activities/Flowchart.cs @@ -27,6 +27,7 @@ public Flowchart([CallerFilePath] string? source = default, [CallerLineNumber] i OnSignalReceived(OnScheduleOutcomesAsync); OnSignalReceived(OnScheduleChildActivityAsync); OnSignalReceived(OnActivityCanceledAsync); + OnSignalReceived(OnEndSignalReceived); } /// @@ -144,8 +145,8 @@ private async ValueTask OnChildCompletedAsync(ActivityCompletedContext context) var completedActivity = completedActivityContext.Activity; var result = context.Result; - bool isBreaking = flowchartContext.GetIsBreaking(); - if (isBreaking) + bool isEnding = flowchartContext.GetIsEnding(); + if (isEnding) { await flowchartContext.CompleteActivityAsync(); return; @@ -293,4 +294,9 @@ private async ValueTask OnActivityCanceledAsync(CancelSignal signal, SignalConte { await CompleteIfNoPendingWorkAsync(context.ReceiverActivityExecutionContext); } + + private void OnEndSignalReceived(EndSignal signal, SignalContext context) + { + context.ReceverActivityExecutionContext.SetIsEnding(); + } } From c0390c670c3c99a5d1eb8d61215a2b6a39134541 Mon Sep 17 00:00:00 2001 From: iio888 <102009054+iio888@users.noreply.github.com> Date: Tue, 20 Aug 2024 10:42:16 +0800 Subject: [PATCH 12/17] Send EndSignal when Break --- src/modules/Elsa.Workflows.Core/Activities/Break.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/modules/Elsa.Workflows.Core/Activities/Break.cs b/src/modules/Elsa.Workflows.Core/Activities/Break.cs index 23d54fbb8a..d12ead5c7f 100644 --- a/src/modules/Elsa.Workflows.Core/Activities/Break.cs +++ b/src/modules/Elsa.Workflows.Core/Activities/Break.cs @@ -24,5 +24,6 @@ protected override async ValueTask ExecuteAsync(ActivityExecutionContext context { // Send a signal to the parent scope to break out of the loop. await context.SendSignalAsync(new BreakSignal()); + await context.SendSignalAsync(new EndSignal()); } -} \ No newline at end of file +} From ff003f09d8e6f2b8235b9d0cbf6ad0de33aae916 Mon Sep 17 00:00:00 2001 From: iio888 <102009054+iio888@users.noreply.github.com> Date: Tue, 20 Aug 2024 10:44:38 +0800 Subject: [PATCH 13/17] Prevent bubbling when received EndSignal --- .../Activities/Flowchart/Activities/Flowchart.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/modules/Elsa.Workflows.Core/Activities/Flowchart/Activities/Flowchart.cs b/src/modules/Elsa.Workflows.Core/Activities/Flowchart/Activities/Flowchart.cs index ddd551e6ad..069a4ed99d 100644 --- a/src/modules/Elsa.Workflows.Core/Activities/Flowchart/Activities/Flowchart.cs +++ b/src/modules/Elsa.Workflows.Core/Activities/Flowchart/Activities/Flowchart.cs @@ -297,6 +297,8 @@ private async ValueTask OnActivityCanceledAsync(CancelSignal signal, SignalConte private void OnEndSignalReceived(EndSignal signal, SignalContext context) { + // Prevent bullbing. + context.StopPropagation(); context.ReceverActivityExecutionContext.SetIsEnding(); } } From 7044f86d9c1b61601339705f6abe1b53c071f5d1 Mon Sep 17 00:00:00 2001 From: iio888 <102009054+iio888@users.noreply.github.com> Date: Thu, 5 Sep 2024 20:23:37 +0800 Subject: [PATCH 14/17] Remove Sending EndSignal in Break Activity --- src/modules/Elsa.Workflows.Core/Activities/Break.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/modules/Elsa.Workflows.Core/Activities/Break.cs b/src/modules/Elsa.Workflows.Core/Activities/Break.cs index d12ead5c7f..eefa0f7889 100644 --- a/src/modules/Elsa.Workflows.Core/Activities/Break.cs +++ b/src/modules/Elsa.Workflows.Core/Activities/Break.cs @@ -24,6 +24,5 @@ protected override async ValueTask ExecuteAsync(ActivityExecutionContext context { // Send a signal to the parent scope to break out of the loop. await context.SendSignalAsync(new BreakSignal()); - await context.SendSignalAsync(new EndSignal()); } } From dca229eb5d07199f8f93d1de69dd89d445aa8d1d Mon Sep 17 00:00:00 2001 From: iio888 <102009054+iio888@users.noreply.github.com> Date: Thu, 5 Sep 2024 20:35:11 +0800 Subject: [PATCH 15/17] Receive BreakSignal in Flowchart --- .../Activities/Flowchart/Activities/Flowchart.cs | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/modules/Elsa.Workflows.Core/Activities/Flowchart/Activities/Flowchart.cs b/src/modules/Elsa.Workflows.Core/Activities/Flowchart/Activities/Flowchart.cs index 069a4ed99d..01ae201868 100644 --- a/src/modules/Elsa.Workflows.Core/Activities/Flowchart/Activities/Flowchart.cs +++ b/src/modules/Elsa.Workflows.Core/Activities/Flowchart/Activities/Flowchart.cs @@ -27,6 +27,8 @@ public Flowchart([CallerFilePath] string? source = default, [CallerLineNumber] i OnSignalReceived(OnScheduleOutcomesAsync); OnSignalReceived(OnScheduleChildActivityAsync); OnSignalReceived(OnActivityCanceledAsync); + + OnSignalReceived(OnBreakSignalReceived); OnSignalReceived(OnEndSignalReceived); } @@ -145,8 +147,9 @@ private async ValueTask OnChildCompletedAsync(ActivityCompletedContext context) var completedActivity = completedActivityContext.Activity; var result = context.Result; + bool isBreaking = flowchartContext.GetIsBreaking(); bool isEnding = flowchartContext.GetIsEnding(); - if (isEnding) + if (isBreaking || isEnding) { await flowchartContext.CompleteActivityAsync(); return; @@ -295,10 +298,17 @@ private async ValueTask OnActivityCanceledAsync(CancelSignal signal, SignalConte await CompleteIfNoPendingWorkAsync(context.ReceiverActivityExecutionContext); } + private void OnBreakSignalReceived(BreakSignal signal, SignalContext context) + { + // Prevent Bubbling + context.StopPropagation(); + context.ReceiverActivityExecutionContext.SetIsBreaking(); + } + private void OnEndSignalReceived(EndSignal signal, SignalContext context) { - // Prevent bullbing. + // Prevent bubbling. context.StopPropagation(); - context.ReceverActivityExecutionContext.SetIsEnding(); + context.ReceiverActivityExecutionContext.SetIsEnding(); } } From 184ca1e94d121621236ec2772d5bd9abd070155e Mon Sep 17 00:00:00 2001 From: iio888 <102009054+iio888@users.noreply.github.com> Date: Thu, 5 Sep 2024 20:40:12 +0800 Subject: [PATCH 16/17] Remove StopPropagation in BreakSignal --- .../Activities/Flowchart/Activities/Flowchart.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/modules/Elsa.Workflows.Core/Activities/Flowchart/Activities/Flowchart.cs b/src/modules/Elsa.Workflows.Core/Activities/Flowchart/Activities/Flowchart.cs index 01ae201868..8bd50036cf 100644 --- a/src/modules/Elsa.Workflows.Core/Activities/Flowchart/Activities/Flowchart.cs +++ b/src/modules/Elsa.Workflows.Core/Activities/Flowchart/Activities/Flowchart.cs @@ -300,8 +300,6 @@ private async ValueTask OnActivityCanceledAsync(CancelSignal signal, SignalConte private void OnBreakSignalReceived(BreakSignal signal, SignalContext context) { - // Prevent Bubbling - context.StopPropagation(); context.ReceiverActivityExecutionContext.SetIsBreaking(); } From f0f7c0c0560c6e33844a701d33d4b35ddc56fb78 Mon Sep 17 00:00:00 2001 From: iio888 <102009054+iio888@users.noreply.github.com> Date: Fri, 13 Sep 2024 10:46:14 +0800 Subject: [PATCH 17/17] Fix spell error --- src/modules/Elsa.Workflows.Core/Signals/EndSignal.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/Elsa.Workflows.Core/Signals/EndSignal.cs b/src/modules/Elsa.Workflows.Core/Signals/EndSignal.cs index c45a4a6a40..18ad0368e6 100644 --- a/src/modules/Elsa.Workflows.Core/Signals/EndSignal.cs +++ b/src/modules/Elsa.Workflows.Core/Signals/EndSignal.cs @@ -1,3 +1,3 @@ -namespaces Elsa.Workflows.Signals; +namespace Elsa.Workflows.Signals; public record EndSignal;