Skip to content

Commit 4cab84e

Browse files
committed
schedule step
1 parent cdecaa4 commit 4cab84e

File tree

8 files changed

+125
-1
lines changed

8 files changed

+125
-1
lines changed

src/WorkflowCore/Interface/IStepBuilder.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,13 @@ public interface IStepBuilder<TData, TStepBody>
4545
/// <returns></returns>
4646
IStepBuilder<TData, InlineStepBody> Then(Func<IStepExecutionContext, ExecutionResult> body);
4747

48+
/// <summary>
49+
/// Specify an inline next step in the workflow
50+
/// </summary>
51+
/// <param name="body"></param>
52+
/// <returns></returns>
53+
IStepBuilder<TData, ActionStepBody> Then(Action<IStepExecutionContext> body);
54+
4855
/// <summary>
4956
/// Configure an outcome for this step, then wire it to another step
5057
/// </summary>
@@ -126,5 +133,7 @@ public interface IStepBuilder<TData, TStepBody>
126133
IContainerStepBuilder<TData, When, OutcomeSwitch> When(Expression<Func<TData, object>> outcomeValue, string label = null);
127134

128135
IParallelStepBuilder<TData, Sequence> Parallel();
136+
137+
IContainerStepBuilder<TData, Schedule, TStepBody> Schedule(Expression<Func<TData, TimeSpan>> time);
129138
}
130139
}

src/WorkflowCore/Interface/IWorkflowBuilder.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ public interface IWorkflowBuilder<TData> : IWorkflowBuilder
2424

2525
IStepBuilder<TData, InlineStepBody> StartWith(Func<IStepExecutionContext, ExecutionResult> body);
2626

27+
IStepBuilder<TData, ActionStepBody> StartWith(Action<IStepExecutionContext> body);
28+
2729
IEnumerable<WorkflowStep> GetUpstreamSteps(int id);
2830

2931
IWorkflowBuilder<TData> UseDefaultErrorBehavior(WorkflowErrorHandling behavior, TimeSpan? retryInterval = null);
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
5+
namespace WorkflowCore.Models
6+
{
7+
public class SchedulePersistenceData
8+
{
9+
public bool Elapsed { get; set; }
10+
11+
}
12+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Linq.Expressions;
5+
using System.Threading.Tasks;
6+
using WorkflowCore.Interface;
7+
using WorkflowCore.Models;
8+
9+
namespace WorkflowCore.Primitives
10+
{
11+
public class ActionStepBody : StepBody
12+
{
13+
public Action<IStepExecutionContext> Body { get; set; }
14+
15+
public override ExecutionResult Run(IStepExecutionContext context)
16+
{
17+
Body(context);
18+
return ExecutionResult.Next();
19+
}
20+
}
21+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Threading.Tasks;
5+
using WorkflowCore.Interface;
6+
using WorkflowCore.Models;
7+
8+
namespace WorkflowCore.Primitives
9+
{
10+
public class Schedule : ContainerStepBody
11+
{
12+
public TimeSpan Period { get; set; }
13+
14+
public override ExecutionResult Run(IStepExecutionContext context)
15+
{
16+
if (context.PersistenceData == null)
17+
return ExecutionResult.Sleep(Period, new SchedulePersistenceData() { Elapsed = false });
18+
19+
20+
if (context.PersistenceData is SchedulePersistenceData)
21+
{
22+
if (!((SchedulePersistenceData) context.PersistenceData).Elapsed)
23+
return ExecutionResult.Branch(new List<object>() { null }, new SchedulePersistenceData() { Elapsed = true });
24+
25+
var complete = true;
26+
27+
foreach (var childId in context.ExecutionPointer.Children)
28+
complete = complete && IsBranchComplete(context.Workflow.ExecutionPointers, childId);
29+
30+
if (complete)
31+
return ExecutionResult.Next();
32+
33+
return ExecutionResult.Persist(context.PersistenceData);
34+
}
35+
36+
throw new ArgumentException();
37+
}
38+
}
39+
}

src/WorkflowCore/Services/StepBuilder.cs

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,16 @@ public IStepBuilder<TData, InlineStepBody> Then(Func<IStepExecutionContext, Exec
6363
return stepBuilder;
6464
}
6565

66+
public IStepBuilder<TData, ActionStepBody> Then(Action<IStepExecutionContext> body)
67+
{
68+
var newStep = new WorkflowStep<ActionStepBody>();
69+
WorkflowBuilder.AddStep(newStep);
70+
var stepBuilder = new StepBuilder<TData, ActionStepBody>(WorkflowBuilder, newStep);
71+
stepBuilder.Input(x => x.Body, x => body);
72+
Step.Outcomes.Add(new StepOutcome() { NextStep = newStep.Id });
73+
return stepBuilder;
74+
}
75+
6676
public IStepOutcomeBuilder<TData> When(object outcomeValue, string label = null)
6777
{
6878
StepOutcome result = new StepOutcome();
@@ -274,7 +284,7 @@ public IContainerStepBuilder<TData, When, OutcomeSwitch> When(Expression<Func<TD
274284

275285
WorkflowBuilder.AddStep(newStep);
276286
var stepBuilder = new SkipStepBuilder<TData, When, OutcomeSwitch>(WorkflowBuilder, newStep, switchBuilder);
277-
287+
278288
switchBuilder.Step.Children.Add(newStep.Id);
279289

280290
return stepBuilder;
@@ -292,6 +302,27 @@ public IParallelStepBuilder<TData, Sequence> Parallel()
292302
return stepBuilder;
293303
}
294304

305+
public IContainerStepBuilder<TData, Schedule, TStepBody> Schedule(Expression<Func<TData, TimeSpan>> time)
306+
{
307+
var newStep = new WorkflowStep<Schedule>();
308+
309+
Expression<Func<Schedule, TimeSpan>> inputExpr = (x => x.Period);
310+
311+
var mapping = new DataMapping()
312+
{
313+
Source = time,
314+
Target = inputExpr
315+
};
316+
newStep.Inputs.Add(mapping);
317+
318+
WorkflowBuilder.AddStep(newStep);
319+
var stepBuilder = new SkipStepBuilder<TData, Schedule, TStepBody>(WorkflowBuilder, newStep, this);
320+
321+
Step.Outcomes.Add(new StepOutcome() { NextStep = newStep.Id });
322+
323+
return stepBuilder;
324+
}
325+
295326
public IStepBuilder<TData, TStepBody> Do(Action<IWorkflowBuilder<TData>> builder)
296327
{
297328
builder.Invoke(WorkflowBuilder);

src/WorkflowCore/Services/WorkflowBuilder.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,15 @@ public IStepBuilder<TData, InlineStepBody> StartWith(Func<IStepExecutionContext,
8282
return stepBuilder;
8383
}
8484

85+
public IStepBuilder<TData, ActionStepBody> StartWith(Action<IStepExecutionContext> body)
86+
{
87+
var newStep = new WorkflowStep<ActionStepBody>();
88+
AddStep(newStep);
89+
var stepBuilder = new StepBuilder<TData, ActionStepBody>(this, newStep);
90+
stepBuilder.Input(x => x.Body, x => body);
91+
return stepBuilder;
92+
}
93+
8594
public IEnumerable<WorkflowStep> GetUpstreamSteps(int id)
8695
{
8796
return Steps.Where(x => x.Outcomes.Any(y => y.NextStep == id)).ToList();

src/samples/WorkflowCore.Sample01/Program.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ private static IServiceProvider ConfigureServices()
3434
IServiceCollection services = new ServiceCollection();
3535
services.AddLogging();
3636
services.AddWorkflow();
37+
//services.AddWorkflow(x => x.UseMongoDB(@"mongodb://localhost:27017", "workflow"));
3738
services.AddTransient<GoodbyeWorld>();
3839

3940
var serviceProvider = services.BuildServiceProvider();

0 commit comments

Comments
 (0)