Skip to content

Commit 2d1523d

Browse files
committed
cancellable waitfor
1 parent c4ae83b commit 2d1523d

File tree

6 files changed

+99
-13
lines changed

6 files changed

+99
-13
lines changed

ReleaseNotes/1.3.3.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Workflow Core 1.3.3
2+
3+
* Added cancel condition parameter to `WaitFor` methoda on the step builder

WorkflowCore.sln

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
Microsoft Visual Studio Solution File, Format Version 12.00
33
# Visual Studio 15
4-
VisualStudioVersion = 15.0.26730.16
4+
VisualStudioVersion = 15.0.26730.3
55
MinimumVisualStudioVersion = 10.0.40219.1
66
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{EF47161E-E399-451C-BDE8-E92AAD3BD761}"
77
EndProject
@@ -87,6 +87,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ReleaseNotes", "ReleaseNote
8787
ReleaseNotes\1.2.8.md = ReleaseNotes\1.2.8.md
8888
ReleaseNotes\1.2.9.md = ReleaseNotes\1.2.9.md
8989
ReleaseNotes\1.3.0.md = ReleaseNotes\1.3.0.md
90+
ReleaseNotes\1.3.2.md = ReleaseNotes\1.3.2.md
91+
ReleaseNotes\1.3.3.md = ReleaseNotes\1.3.3.md
9092
EndProjectSection
9193
EndProject
9294
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WorkflowCore.Sample14", "src\samples\WorkflowCore.Sample14\WorkflowCore.Sample14.csproj", "{6BC66637-B42A-4334-ADFB-DBEC9F29D293}"
@@ -97,7 +99,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WorkflowCore.TestSample01",
9799
EndProject
98100
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Docker.Testify", "test\Docker.Testify\Docker.Testify.csproj", "{EC497168-5347-4E70-9D9E-9C2F826C1CDF}"
99101
EndProject
100-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WorkflowCore.Sample15", "WorkflowCore.Sample15\WorkflowCore.Sample15.csproj", "{F9FD8357-C299-4CF4-B0D4-D3D5E45AAAA3}"
102+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WorkflowCore.Sample15", "WorkflowCore.Sample15\WorkflowCore.Sample15.csproj", "{F9FD8357-C299-4CF4-B0D4-D3D5E45AAAA3}"
101103
EndProject
102104
Global
103105
GlobalSection(SolutionConfigurationPlatforms) = preSolution

src/WorkflowCore/Interface/IStepBuilder.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,18 +92,20 @@ public interface IStepBuilder<TData, TStepBody>
9292
/// <param name="eventName">The name used to identify the kind of event to wait for</param>
9393
/// <param name="eventKey">A specific key value within the context of the event to wait for</param>
9494
/// <param name="effectiveDate">Listen for events as of this effective date</param>
95+
/// <param name="cancelCondition">A conditon that when true will cancel this WaitFor</param>
9596
/// <returns></returns>
96-
IStepBuilder<TData, WaitFor> WaitFor(string eventName, Expression<Func<TData, string>> eventKey, Expression<Func<TData, DateTime>> effectiveDate = null);
97+
IStepBuilder<TData, WaitFor> WaitFor(string eventName, Expression<Func<TData, string>> eventKey, Expression<Func<TData, DateTime>> effectiveDate = null, Expression<Func<TData, bool>> cancelCondition = null);
9798

9899
/// <summary>
99100
/// Wait here until to specified event is published
100101
/// </summary>
101102
/// <param name="eventName">The name used to identify the kind of event to wait for</param>
102103
/// <param name="eventKey">A specific key value within the context of the event to wait for</param>
103104
/// <param name="effectiveDate">Listen for events as of this effective date</param>
105+
/// <param name="cancelCondition">A conditon that when true will cancel this WaitFor</param>
104106
/// <returns></returns>
105-
IStepBuilder<TData, WaitFor> WaitFor(string eventName, Expression<Func<TData, IStepExecutionContext, string>> eventKey, Expression<Func<TData, DateTime>> effectiveDate = null);
106-
107+
IStepBuilder<TData, WaitFor> WaitFor(string eventName, Expression<Func<TData, IStepExecutionContext, string>> eventKey, Expression<Func<TData, DateTime>> effectiveDate = null, Expression<Func<TData, bool>> cancelCondition = null);
108+
107109
IStepBuilder<TData, TStep> End<TStep>(string name) where TStep : IStepBody;
108110

109111
/// <summary>

src/WorkflowCore/Services/FluentBuilders/StepBuilder.cs

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -109,9 +109,15 @@ public IStepBuilder<TData, TStepBody> Output<TOutput>(Expression<Func<TData, TOu
109109
return this;
110110
}
111111

112-
public IStepBuilder<TData, WaitFor> WaitFor(string eventName, Expression<Func<TData, string>> eventKey, Expression<Func<TData, DateTime>> effectiveDate = null)
112+
public IStepBuilder<TData, WaitFor> WaitFor(string eventName, Expression<Func<TData, string>> eventKey, Expression<Func<TData, DateTime>> effectiveDate = null, Expression<Func<TData, bool>> cancelCondition = null)
113113
{
114-
var newStep = new WorkflowStep<WaitFor>();
114+
WorkflowStep<WaitFor> newStep;
115+
116+
if (cancelCondition != null)
117+
newStep = new CancellableStep<WaitFor, TData>(cancelCondition);
118+
else
119+
newStep = new WorkflowStep<WaitFor>();
120+
115121
WorkflowBuilder.AddStep(newStep);
116122
var stepBuilder = new StepBuilder<TData, WaitFor>(WorkflowBuilder, newStep);
117123
stepBuilder.Input((step) => step.EventName, (data) => eventName);
@@ -126,9 +132,15 @@ public IStepBuilder<TData, WaitFor> WaitFor(string eventName, Expression<Func<TD
126132
return stepBuilder;
127133
}
128134

129-
public IStepBuilder<TData, WaitFor> WaitFor(string eventName, Expression<Func<TData, IStepExecutionContext, string>> eventKey, Expression<Func<TData, DateTime>> effectiveDate = null)
135+
public IStepBuilder<TData, WaitFor> WaitFor(string eventName, Expression<Func<TData, IStepExecutionContext, string>> eventKey, Expression<Func<TData, DateTime>> effectiveDate = null, Expression<Func<TData, bool>> cancelCondition = null)
130136
{
131-
var newStep = new WorkflowStep<WaitFor>();
137+
WorkflowStep<WaitFor> newStep;
138+
139+
if (cancelCondition != null)
140+
newStep = new CancellableStep<WaitFor, TData>(cancelCondition);
141+
else
142+
newStep = new WorkflowStep<WaitFor>();
143+
132144
WorkflowBuilder.AddStep(newStep);
133145
var stepBuilder = new StepBuilder<TData, WaitFor>(WorkflowBuilder, newStep);
134146
stepBuilder.Input((step) => step.EventName, (data) => eventName);
@@ -142,7 +154,7 @@ public IStepBuilder<TData, WaitFor> WaitFor(string eventName, Expression<Func<TD
142154
Step.Outcomes.Add(new StepOutcome() { NextStep = newStep.Id });
143155
return stepBuilder;
144156
}
145-
157+
146158
public IStepBuilder<TData, TStep> End<TStep>(string name) where TStep : IStepBody
147159
{
148160
var ancestor = IterateParents(Step.Id, name);

src/WorkflowCore/WorkflowCore.csproj

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@
1818
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
1919
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
2020
<Description>Workflow Core is a light weight workflow engine targeting .NET Standard.</Description>
21-
<Version>1.3.2</Version>
22-
<AssemblyVersion>1.3.2.0</AssemblyVersion>
23-
<FileVersion>1.3.2.0</FileVersion>
21+
<Version>1.3.3</Version>
22+
<AssemblyVersion>1.3.3.0</AssemblyVersion>
23+
<FileVersion>1.3.3.0</FileVersion>
2424
<PackageReleaseNotes></PackageReleaseNotes>
2525
</PropertyGroup>
2626

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
using WorkflowCore.Interface;
5+
using WorkflowCore.Models;
6+
using Xunit;
7+
using FluentAssertions;
8+
using System.Linq;
9+
using WorkflowCore.Testing;
10+
11+
namespace WorkflowCore.IntegrationTests.Scenarios
12+
{
13+
public class CancelledEventScenario : WorkflowTest<CancelledEventScenario.EventWorkflow, CancelledEventScenario.MyDataClass>
14+
{
15+
public class MyDataClass
16+
{
17+
public string StrValue { get; set; }
18+
}
19+
20+
public class EventWorkflow : IWorkflow<MyDataClass>
21+
{
22+
public static bool Event1Fired = false;
23+
public static bool Event2Fired = false;
24+
25+
public string Id => "CancelledEventWorkflow";
26+
public int Version => 1;
27+
public void Build(IWorkflowBuilder<MyDataClass> builder)
28+
{
29+
builder
30+
.StartWith(context => ExecutionResult.Next())
31+
.Parallel()
32+
.Do(branch1 => branch1
33+
.StartWith(context => ExecutionResult.Next())
34+
.WaitFor("Event1", (data, context) => context.Workflow.Id, null, data => !string.IsNullOrEmpty(data.StrValue))
35+
.Output(data => data.StrValue, step => step.EventData)
36+
.Then(context => Event1Fired = true))
37+
.Do(branch2 => branch2
38+
.StartWith(context => ExecutionResult.Next())
39+
.WaitFor("Event2", (data, context) => context.Workflow.Id, null, data => !string.IsNullOrEmpty(data.StrValue))
40+
.Output(data => data.StrValue, step => step.EventData)
41+
.Then(context => Event2Fired = true))
42+
.Join();
43+
}
44+
}
45+
46+
public CancelledEventScenario()
47+
{
48+
Setup();
49+
}
50+
51+
[Fact]
52+
public void Scenario()
53+
{
54+
var workflowId = StartWorkflow(new MyDataClass());
55+
WaitForEventSubscription("Event1", workflowId, TimeSpan.FromSeconds(30));
56+
WaitForEventSubscription("Event2", workflowId, TimeSpan.FromSeconds(30));
57+
Host.PublishEvent("Event2", workflowId, "Pass");
58+
WaitForWorkflowToComplete(workflowId, TimeSpan.FromSeconds(30));
59+
60+
GetStatus(workflowId).Should().Be(WorkflowStatus.Complete);
61+
UnhandledStepErrors.Count.Should().Be(0);
62+
GetData(workflowId).StrValue.Should().Be("Pass");
63+
EventWorkflow.Event1Fired.Should().BeFalse();
64+
EventWorkflow.Event2Fired.Should().BeTrue();
65+
}
66+
}
67+
}

0 commit comments

Comments
 (0)