Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FIX] cannot end a flowchart when a End is Then Activity in If #5899

Open
wants to merge 26 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
b664160
Update End.cs
iio888 Aug 14, 2024
c8781b4
Update Flowchart.cs
iio888 Aug 14, 2024
489ed12
Create BreakWhileFlowchartWorkflow.cs
iio888 Aug 14, 2024
93c3417
Update BreakTests.cs
iio888 Aug 14, 2024
5eaf2dc
Create EndFlowchartWorkflow.cs
iio888 Aug 14, 2024
62d2345
Create EndTests.cs
iio888 Aug 14, 2024
6dd52ea
Merge branch 'main' into fix-end-flowchart
iio888 Aug 15, 2024
8f853b2
Clean Flowchart.cs
iio888 Aug 15, 2024
36ebf0d
Create EndSignal.cs
iio888 Aug 17, 2024
b461cc1
Send EndSignal in End
iio888 Aug 17, 2024
7d4fd32
Create EndSignalActivityExecutionContextExtensions.cs
iio888 Aug 17, 2024
c599a95
Change BreakSignal to EndSignal
iio888 Aug 17, 2024
7ae703f
Merge branch 'main' into fix-end-flowchart
iio888 Aug 18, 2024
822420e
Merge branch 'main' into fix-end-flowchart
iio888 Aug 19, 2024
c0390c6
Send EndSignal when Break
iio888 Aug 20, 2024
ff003f0
Prevent bubbling when received EndSignal
iio888 Aug 20, 2024
8a8afb2
Merge branch 'main' into fix-end-flowchart
sfmskywalker Aug 30, 2024
09cffa1
Merge branch 'elsa-workflows:main' into fix-end-flowchart
iio888 Sep 5, 2024
7044f86
Remove Sending EndSignal in Break Activity
iio888 Sep 5, 2024
dca229e
Receive BreakSignal in Flowchart
iio888 Sep 5, 2024
184ca1e
Remove StopPropagation in BreakSignal
iio888 Sep 5, 2024
456ad94
Merge branch 'main' into fix-end-flowchart
iio888 Sep 6, 2024
c11ffae
Merge branch 'main' into fix-end-flowchart
iio888 Sep 9, 2024
9d6c4ff
Merge branch 'main' into fix-end-flowchart
sfmskywalker Sep 12, 2024
f0f7c0c
Fix spell error
iio888 Sep 13, 2024
1faec5b
Merge branch 'main' into fix-end-flowchart
iio888 Sep 17, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/modules/Elsa.Workflows.Core/Activities/Break.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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());
sfmskywalker marked this conversation as resolved.
Show resolved Hide resolved
}
}
}
7 changes: 6 additions & 1 deletion src/modules/Elsa.Workflows.Core/Activities/End.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,9 @@ public class End : CodeActivity, ITerminalNode
public End([CallerFilePath] string? source = default, [CallerLineNumber] int? line = default) : base(source, line)
{
}
}

protected async override ValueTask ExecuteAsync(ActivityExecutionContext context)
{
await context.SendSignalAsync(new EndSignal());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public Flowchart([CallerFilePath] string? source = default, [CallerLineNumber] i
OnSignalReceived<ScheduleActivityOutcomes>(OnScheduleOutcomesAsync);
OnSignalReceived<ScheduleChildActivity>(OnScheduleChildActivityAsync);
OnSignalReceived<CancelSignal>(OnActivityCanceledAsync);
OnSignalReceived<EndSignal>(OnEndSignalReceived);
}

/// <summary>
Expand Down Expand Up @@ -144,6 +145,13 @@ private async ValueTask OnChildCompletedAsync(ActivityCompletedContext context)
var completedActivity = completedActivityContext.Activity;
var result = context.Result;

bool isEnding = flowchartContext.GetIsEnding();
if (isEnding)
{
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
Expand Down Expand Up @@ -286,4 +294,11 @@ private async ValueTask OnActivityCanceledAsync(CancelSignal signal, SignalConte
{
await CompleteIfNoPendingWorkAsync(context.ReceiverActivityExecutionContext);
}
}

private void OnEndSignalReceived(EndSignal signal, SignalContext context)
{
// Prevent bullbing.
context.StopPropagation();
context.ReceverActivityExecutionContext.SetIsEnding();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
namespace Elsa.Workflows.Extensions;

public static class EndSignalActivityExecutionContextExtensions
{
/// <summary>
/// Gets a value indicating whether the current activity is ending out of a flowchart.
/// </summary>
public static bool GetIsEnding(this ActivityExecutionContext context) => context.GetProperty<bool>("IsEnding");

/// <summary>
/// Sets a value indicating whether the current activity is ending out of a flowchart.
/// <summary>
public static void SetIsEnding(this ActivityExecutionContext context) => context.SetProperty("IsEnding", true);
}
3 changes: 3 additions & 0 deletions src/modules/Elsa.Workflows.Core/Signals/EndSignal.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
namespaces Elsa.Workflows.Signals;

public record EndSignal;
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,13 @@ public async Task Test5()
var lines = _capturingTextWriter.Lines.ToList();
Assert.Equal(new[] { "Start", "1", "2", "End" }, lines);
}
}

[Fact(DisplayName = "Break While whin a Flowchart")]
public async Task Test6()
{
await _services.PopulateRegistriesAsync();
await _workflowRunner.RunAsync<BreakWhileFlowchartWorkflow>();
var lines = _capturingTextWriter.Lines.ToList();
Assert.Equal(new[] { "start" }, lines);
}
}
Original file line number Diff line number Diff line change
@@ -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),
}
});
}
}
Original file line number Diff line number Diff line change
@@ -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),
}
};
}
}
Original file line number Diff line number Diff line change
@@ -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<IWorkflowRunner>();
}

[Fact(DisplayName = "End a flowchart when the End is nested in If")]
public async Task Test1()
{
await _services.PopulateRegistriesAsync();
await _workflowRunner.RunAsync<EndFlowchartWorkflow>();
var lines = _capturingTextWriter.Lines.ToList();
Assert.Equal(new[] { "start" }, lines);
}
}
Loading