Skip to content

Commit 27926fa

Browse files
authored
Merge pull request #38 from danielgerlag/fork
Parallel steps
2 parents 21f0800 + 724a95d commit 27926fa

File tree

16 files changed

+395
-7
lines changed

16 files changed

+395
-7
lines changed

WorkflowCore.sln

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WorkflowCore.Tests.Sqlite",
8686
EndProject
8787
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WorkflowCore.LockProviders.SqlServer", "src\providers\WorkflowCore.LockProviders.SqlServer\WorkflowCore.LockProviders.SqlServer.csproj", "{AAE2E9F9-37EF-4AE1-A200-D37417C9040C}"
8888
EndProject
89+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WorkflowCore.Sample13", "src\samples\WorkflowCore.Sample13\WorkflowCore.Sample13.csproj", "{77C49ACA-203E-428C-A4DB-114DFE454988}"
90+
EndProject
8991
Global
9092
GlobalSection(SolutionConfigurationPlatforms) = preSolution
9193
Debug|Any CPU = Debug|Any CPU
@@ -228,6 +230,10 @@ Global
228230
{AAE2E9F9-37EF-4AE1-A200-D37417C9040C}.Debug|Any CPU.Build.0 = Debug|Any CPU
229231
{AAE2E9F9-37EF-4AE1-A200-D37417C9040C}.Release|Any CPU.ActiveCfg = Release|Any CPU
230232
{AAE2E9F9-37EF-4AE1-A200-D37417C9040C}.Release|Any CPU.Build.0 = Release|Any CPU
233+
{77C49ACA-203E-428C-A4DB-114DFE454988}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
234+
{77C49ACA-203E-428C-A4DB-114DFE454988}.Debug|Any CPU.Build.0 = Debug|Any CPU
235+
{77C49ACA-203E-428C-A4DB-114DFE454988}.Release|Any CPU.ActiveCfg = Release|Any CPU
236+
{77C49ACA-203E-428C-A4DB-114DFE454988}.Release|Any CPU.Build.0 = Release|Any CPU
231237
EndGlobalSection
232238
GlobalSection(SolutionProperties) = preSolution
233239
HideSolutionNode = FALSE
@@ -270,5 +276,6 @@ Global
270276
{BB776411-D279-419F-8697-5C6F52BCD5CD} = {5080DB09-CBE8-4C45-9957-C3BB7651755E}
271277
{F9F8F9CD-01D9-468B-856D-6A87F0762A01} = {E6CEAD8D-F565-471E-A0DC-676F54EAEDEB}
272278
{AAE2E9F9-37EF-4AE1-A200-D37417C9040C} = {2EEE6ABD-EE9B-473F-AF2D-6DABB85D7BA2}
279+
{77C49ACA-203E-428C-A4DB-114DFE454988} = {5080DB09-CBE8-4C45-9957-C3BB7651755E}
273280
EndGlobalSection
274281
EndGlobal
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
using WorkflowCore.Primitives;
5+
6+
namespace WorkflowCore.Interface
7+
{
8+
public interface IParallelStepBuilder<TData, TStepBody>
9+
where TStepBody : IStepBody
10+
{
11+
IParallelStepBuilder<TData, TStepBody> Do(Action<IWorkflowBuilder<TData>> builder);
12+
IStepBuilder<TData, Sequence> Join();
13+
}
14+
}

src/WorkflowCore/Interface/IStepBuilder.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,5 +101,7 @@ public interface IStepBuilder<TData, TStepBody>
101101
/// <param name="outcomeValue"></param>
102102
/// <returns></returns>
103103
IContainerStepBuilder<TData, When, OutcomeSwitch> When(Expression<Func<TData, object>> outcomeValue, string label = null);
104+
105+
IParallelStepBuilder<TData, Sequence> Parallel();
104106
}
105107
}

src/WorkflowCore/Interface/IWorkflowBuilder.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,14 @@ namespace WorkflowCore.Interface
88
{
99
public interface IWorkflowBuilder
1010
{
11-
int InitialStep { get; set; }
11+
int LastStep { get; }
1212

1313
IWorkflowBuilder<T> UseData<T>();
1414

1515
WorkflowDefinition Build(string id, int version);
1616

17-
void AddStep(WorkflowStep step);
17+
void AddStep(WorkflowStep step);
18+
1819
}
1920

2021
public interface IWorkflowBuilder<TData> : IWorkflowBuilder
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
using System;
2+
using System.Collections;
3+
using System.Collections.Generic;
4+
using System.Linq;
5+
using System.Linq.Expressions;
6+
using System.Threading.Tasks;
7+
using WorkflowCore.Interface;
8+
using WorkflowCore.Models;
9+
using WorkflowCore.Primitives;
10+
11+
namespace WorkflowCore.Services
12+
{
13+
public class ParallelStepBuilder<TData, TStepBody> : IParallelStepBuilder<TData, TStepBody>
14+
where TStepBody : IStepBody
15+
{
16+
private readonly IStepBuilder<TData, Sequence> _referenceBuilder;
17+
private readonly IStepBuilder<TData, TStepBody> _stepBuilder;
18+
19+
public IWorkflowBuilder<TData> WorkflowBuilder { get; private set; }
20+
21+
public WorkflowStep<TStepBody> Step { get; set; }
22+
23+
public ParallelStepBuilder(IWorkflowBuilder<TData> workflowBuilder, IStepBuilder<TData, TStepBody> stepBuilder, IStepBuilder<TData, Sequence> referenceBuilder)
24+
{
25+
WorkflowBuilder = workflowBuilder;
26+
Step = stepBuilder.Step;
27+
_stepBuilder = stepBuilder;
28+
_referenceBuilder = referenceBuilder;
29+
}
30+
31+
public IParallelStepBuilder<TData, TStepBody> Do(Action<IWorkflowBuilder<TData>> builder)
32+
{
33+
int lastStep = WorkflowBuilder.LastStep;
34+
builder.Invoke(WorkflowBuilder);
35+
Step.Children.Add(lastStep + 1); //TODO: make more elegant
36+
37+
return this;
38+
}
39+
40+
public IStepBuilder<TData, Sequence> Join()
41+
{
42+
return _referenceBuilder;
43+
}
44+
}
45+
}

src/WorkflowCore/Services/StepBuilder.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,18 @@ public IContainerStepBuilder<TData, When, OutcomeSwitch> When(Expression<Func<TD
250250
return stepBuilder;
251251
}
252252

253+
public IParallelStepBuilder<TData, Sequence> Parallel()
254+
{
255+
var newStep = new WorkflowStep<Sequence>();
256+
var newBuilder = new StepBuilder<TData, Sequence>(WorkflowBuilder, newStep);
257+
WorkflowBuilder.AddStep(newStep);
258+
var stepBuilder = new ParallelStepBuilder<TData, Sequence>(WorkflowBuilder, newBuilder, newBuilder);
259+
260+
Step.Outcomes.Add(new StepOutcome() { NextStep = newStep.Id });
261+
262+
return stepBuilder;
263+
}
264+
253265
public IStepBuilder<TData, TStepBody> Do(Action<IWorkflowBuilder<TData>> builder)
254266
{
255267
builder.Invoke(WorkflowBuilder);

src/WorkflowCore/Services/WorkflowBuilder.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,14 @@ namespace WorkflowCore.Services
1010
{
1111
public class WorkflowBuilder : IWorkflowBuilder
1212
{
13-
public int InitialStep { get; set; }
14-
1513
protected List<WorkflowStep> Steps { get; set; } = new List<WorkflowStep>();
1614

1715
protected WorkflowErrorHandling DefaultErrorBehavior = WorkflowErrorHandling.Retry;
1816

1917
protected TimeSpan? DefaultErrorRetryInterval;
2018

19+
public int LastStep => Steps.Max(x => x.Id);
20+
2121
public IWorkflowBuilder<T> UseData<T>()
2222
{
2323
IWorkflowBuilder<T> result = new WorkflowBuilder<T>(Steps);

src/WorkflowCore/WorkflowCore.csproj

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,10 @@
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.2.5</Version>
22-
<AssemblyVersion>1.2.5.0</AssemblyVersion>
23-
<FileVersion>1.2.5.0</FileVersion>
21+
<Version>1.2.6</Version>
22+
<AssemblyVersion>1.2.6.0</AssemblyVersion>
23+
<FileVersion>1.2.6.0</FileVersion>
24+
<PackageReleaseNotes>Added Parallel steps</PackageReleaseNotes>
2425
</PropertyGroup>
2526

2627
<ItemGroup>
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
using WorkflowCore.Interface;
5+
using WorkflowCore.Models;
6+
7+
namespace WorkflowCore.Sample13
8+
{
9+
public class ParallelWorkflow : IWorkflow<MyData>
10+
{
11+
public string Id => "parallel-sample";
12+
public int Version => 1;
13+
14+
public void Build(IWorkflowBuilder<MyData> builder)
15+
{
16+
builder
17+
.StartWith<SayHello>()
18+
.Parallel()
19+
.Do(then =>
20+
then.StartWith<PrintMessage>()
21+
.Input(step => step.Message, data => "Item 1.1")
22+
.Then<PrintMessage>()
23+
.Input(step => step.Message, data => "Item 1.2"))
24+
.Do(then =>
25+
then.StartWith<PrintMessage>()
26+
.Input(step => step.Message, data => "Item 2.1")
27+
.Then<PrintMessage>()
28+
.Input(step => step.Message, data => "Item 2.2"))
29+
.Do(then =>
30+
then.StartWith<PrintMessage>()
31+
.Input(step => step.Message, data => "Item 3.1")
32+
.Then<PrintMessage>()
33+
.Input(step => step.Message, data => "Item 3.2"))
34+
.Join()
35+
.Then<SayGoodbye>();
36+
}
37+
}
38+
39+
public class MyData
40+
{
41+
public int Counter { get; set; }
42+
}
43+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
using System;
2+
using Microsoft.Extensions.DependencyInjection;
3+
using Microsoft.Extensions.Logging;
4+
using WorkflowCore.Interface;
5+
6+
namespace WorkflowCore.Sample13
7+
{
8+
class Program
9+
{
10+
public static void Main(string[] args)
11+
{
12+
IServiceProvider serviceProvider = ConfigureServices();
13+
14+
//start the workflow host
15+
var host = serviceProvider.GetService<IWorkflowHost>();
16+
host.RegisterWorkflow<ParallelWorkflow, MyData>();
17+
host.Start();
18+
19+
Console.WriteLine("Starting workflow...");
20+
string workflowId = host.StartWorkflow("parallel-sample").Result;
21+
22+
Console.ReadLine();
23+
host.Stop();
24+
}
25+
26+
private static IServiceProvider ConfigureServices()
27+
{
28+
//setup dependency injection
29+
IServiceCollection services = new ServiceCollection();
30+
services.AddLogging();
31+
services.AddWorkflow();
32+
//services.AddWorkflow(x => x.UseMongoDB(@"mongodb://localhost:27017", "workflow-test002"));
33+
//services.AddWorkflow(x => x.UseSqlServer(@"Server=.\SQLEXPRESS;Database=WorkflowCoreTest001;Trusted_Connection=True;", true, true));
34+
//services.AddWorkflow(x => x.UseSqlite(@"Data Source=wfc001.db;", true));
35+
36+
37+
var serviceProvider = services.BuildServiceProvider();
38+
39+
//config logging
40+
var loggerFactory = serviceProvider.GetService<ILoggerFactory>();
41+
//loggerFactory.AddDebug(LogLevel.Debug);
42+
return serviceProvider;
43+
}
44+
}
45+
}

0 commit comments

Comments
 (0)