Skip to content

Commit 46a32e0

Browse files
committed
feat(Sdk): Replaced all single task properties (for/do, try, try/catch/do, ...) by maps that guarantee proper ordering
feat(Sdk): Removed the CompositeTaskDefinition and replace it with both DoTaskDefinition and ForkTaskDefinition Signed-off-by: Charles d'Avernas <charles.davernas@neuroglia.io>
1 parent dbcb10f commit 46a32e0

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+750
-411
lines changed

src/ServerlessWorkflow.Sdk.Builders/CompositeTaskDefinitionBuilder.cs

Lines changed: 0 additions & 85 deletions
This file was deleted.
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// Copyright © 2024-Present The Serverless Workflow Specification Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License"),
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
// http://www.apache.org/licenses/LICENSE-2.0
7+
//
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
14+
namespace ServerlessWorkflow.Sdk.Builders;
15+
16+
/// <summary>
17+
/// Represents the default implementation of the <see cref="IDoTaskDefinitionBuilder"/> interface
18+
/// </summary>
19+
public class DoTaskDefinitionBuilder
20+
: TaskDefinitionBuilder<DoTaskDefinition>, IDoTaskDefinitionBuilder
21+
{
22+
23+
/// <summary>
24+
/// Gets/sets a name/definition mapping of the tasks to execute sequentially, if any
25+
/// </summary>
26+
protected Map<string, TaskDefinition>? Tasks { get; set; }
27+
28+
/// <inheritdoc/>
29+
public virtual IDoTaskDefinitionBuilder Do(Action<ITaskDefinitionMapBuilder> setup)
30+
{
31+
ArgumentNullException.ThrowIfNull(setup);
32+
var builder = new TaskDefinitionMapBuilder();
33+
setup(builder);
34+
this.Tasks = builder.Build();
35+
return this;
36+
}
37+
38+
/// <inheritdoc/>
39+
public override DoTaskDefinition Build()
40+
{
41+
if (this.Tasks == null || this.Tasks.Count < 2) throw new NullReferenceException("The execution strategy must define at least two subtasks");
42+
return new()
43+
{
44+
Do = this.Tasks
45+
};
46+
}
47+
48+
}

src/ServerlessWorkflow.Sdk.Builders/ErrorCatcherDefinitionBuilder.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ public class ErrorCatcherDefinitionBuilder
5353
/// <summary>
5454
/// Gets/sets the definition of the task to run when catching an error
5555
/// </summary>
56-
protected TaskDefinition? RetryDo { get; set; }
56+
protected Map<string, TaskDefinition>? RetryDo { get; set; }
5757

5858
/// <inheritdoc/>
5959
public virtual IErrorCatcherDefinitionBuilder Errors(ErrorFilterDefinition filter)
@@ -117,10 +117,11 @@ public virtual IErrorCatcherDefinitionBuilder Retry(Action<IRetryPolicyDefinitio
117117
}
118118

119119
/// <inheritdoc/>
120-
public virtual IErrorCatcherDefinitionBuilder Do(Action<IGenericTaskDefinitionBuilder> setup)
120+
public IErrorCatcherDefinitionBuilder Do(Action<ITaskDefinitionMapBuilder> setup)
121121
{
122122
ArgumentNullException.ThrowIfNull(setup);
123-
var builder = new GenericTaskDefinitionBuilder();
123+
var builder = new TaskDefinitionMapBuilder();
124+
setup(builder);
124125
this.RetryDo = builder.Build();
125126
return this;
126127
}

src/ServerlessWorkflow.Sdk.Builders/ExtensionDefinitionBuilder.cs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,12 @@ public class ExtensionDefinitionBuilder
3333
/// <summary>
3434
/// Gets/sets the definition of the task to run before the extended one
3535
/// </summary>
36-
protected TaskDefinition? BeforeTask { get; set; }
36+
protected Map<string, TaskDefinition>? BeforeTasks { get; set; }
3737

3838
/// <summary>
3939
/// Gets/sets the definition of the task to run after the extended one
4040
/// </summary>
41-
protected TaskDefinition? AfterTask { get; set; }
41+
protected Map<string, TaskDefinition>? AfterTasks { get; set; }
4242

4343
/// <inheritdoc/>
4444
public virtual IExtensionDefinitionBuilder Extend(string taskType)
@@ -57,22 +57,22 @@ public virtual IExtensionDefinitionBuilder When(string when)
5757
}
5858

5959
/// <inheritdoc/>
60-
public virtual IExtensionDefinitionBuilder Before(Action<IGenericTaskDefinitionBuilder> setup)
60+
public virtual IExtensionDefinitionBuilder Before(Action<ITaskDefinitionMapBuilder> setup)
6161
{
6262
ArgumentNullException.ThrowIfNull(setup);
63-
var builder = new GenericTaskDefinitionBuilder();
63+
var builder = new TaskDefinitionMapBuilder();
6464
setup(builder);
65-
this.BeforeTask = builder.Build();
65+
this.BeforeTasks = builder.Build();
6666
return this;
6767
}
6868

6969
/// <inheritdoc/>
70-
public virtual IExtensionDefinitionBuilder After(Action<IGenericTaskDefinitionBuilder> setup)
70+
public virtual IExtensionDefinitionBuilder After(Action<ITaskDefinitionMapBuilder> setup)
7171
{
7272
ArgumentNullException.ThrowIfNull(setup);
73-
var builder = new GenericTaskDefinitionBuilder();
73+
var builder = new TaskDefinitionMapBuilder();
7474
setup(builder);
75-
this.AfterTask = builder.Build();
75+
this.AfterTasks = builder.Build();
7676
return this;
7777
}
7878

@@ -84,8 +84,8 @@ public virtual ExtensionDefinition Build()
8484
{
8585
Extend = this.TaskType,
8686
When = this.WhenExpression,
87-
Before = this.BeforeTask,
88-
After = this.AfterTask
87+
Before = this.BeforeTasks,
88+
After = this.AfterTasks
8989
};
9090
}
9191

src/ServerlessWorkflow.Sdk.Builders/ForTaskDefinitionBuilder.cs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,9 @@ public class ForTaskDefinitionBuilder
3636
protected virtual string? AtVariableName { get; set; }
3737

3838
/// <summary>
39-
/// Gets an <see cref="Action{T}"/> used to setup the task to perform for each iteration
39+
/// Gets/sets a name/definition map of the tasks to perform for each element in the collection to enumerate
4040
/// </summary>
41-
protected virtual Action<IGenericTaskDefinitionBuilder>? DoSetup { get; set; }
41+
protected virtual Map<string, TaskDefinition>? Tasks { get; set; }
4242

4343
/// <inheritdoc/>
4444
public virtual IForTaskDefinitionBuilder Each(string variableName)
@@ -65,10 +65,12 @@ public virtual IForTaskDefinitionBuilder At(string variableName)
6565
}
6666

6767
/// <inheritdoc/>
68-
public virtual IForTaskDefinitionBuilder Do(Action<IGenericTaskDefinitionBuilder> setup)
68+
public virtual IForTaskDefinitionBuilder Do(Action<ITaskDefinitionMapBuilder> setup)
6969
{
7070
ArgumentNullException.ThrowIfNull(setup);
71-
this.DoSetup = setup;
71+
var builder = new TaskDefinitionMapBuilder();
72+
setup(builder);
73+
this.Tasks = builder.Build();
7274
return this;
7375
}
7476

@@ -77,9 +79,7 @@ public override ForTaskDefinition Build()
7779
{
7880
if (string.IsNullOrWhiteSpace(this.EachVariableName)) throw new NullReferenceException("The variable name used to store the iterated items must be set");
7981
if (string.IsNullOrWhiteSpace(this.InExpression)) throw new NullReferenceException("The runtime expression used to resolve the collection to iterate must be set");
80-
if (this.DoSetup == null) throw new NullReferenceException("The task to perform at each iteration must be set");
81-
var taskBuilder = new GenericTaskDefinitionBuilder();
82-
this.DoSetup(taskBuilder);
82+
if (this.Tasks == null || this.Tasks.Count < 1) throw new NullReferenceException("The task to perform at each iteration must be set");
8383
return new()
8484
{
8585
For = new()
@@ -88,7 +88,7 @@ public override ForTaskDefinition Build()
8888
In = this.InExpression,
8989
At = this.AtVariableName
9090
},
91-
Do = taskBuilder.Build()
91+
Do = this.Tasks
9292
};
9393
}
9494

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
// Copyright © 2024-Present The Serverless Workflow Specification Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License"),
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
// http://www.apache.org/licenses/LICENSE-2.0
7+
//
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
14+
namespace ServerlessWorkflow.Sdk.Builders;
15+
16+
/// <summary>
17+
/// Represents the default implementation of the <see cref="IForkTaskDefinitionBuilder"/> interface
18+
/// </summary>
19+
public class ForkTaskDefinitionBuilder
20+
: TaskDefinitionBuilder<ForkTaskDefinition>, IForkTaskDefinitionBuilder
21+
{
22+
23+
/// <summary>
24+
/// Gets/sets a name/definition mapping of the tasks to execute concurrently, if any
25+
/// </summary>
26+
protected Map<string, TaskDefinition>? Tasks { get; set; }
27+
28+
/// <summary>
29+
/// Gets/sets a boolean indicating whether or not the task to execute concurrently should compete each other
30+
/// </summary>
31+
protected bool ShouldCompete { get; set; }
32+
33+
/// <inheritdoc/>
34+
public virtual IForkTaskDefinitionBuilder Branch(Action<ITaskDefinitionMapBuilder> setup)
35+
{
36+
ArgumentNullException.ThrowIfNull(setup);
37+
var builder = new TaskDefinitionMapBuilder();
38+
setup(builder);
39+
this.Tasks = builder.Build();
40+
return this;
41+
}
42+
43+
/// <inheritdoc/>
44+
public virtual IForkTaskDefinitionBuilder Compete()
45+
{
46+
this.ShouldCompete = true;
47+
return this;
48+
}
49+
50+
/// <inheritdoc/>
51+
public override ForkTaskDefinition Build()
52+
{
53+
if (this.Tasks == null || this.Tasks.Count < 2) throw new NullReferenceException("The execution strategy must define at least two subtasks");
54+
return new()
55+
{
56+
Fork = new()
57+
{
58+
Branches = this.Tasks,
59+
Compete = this.ShouldCompete
60+
}
61+
};
62+
}
63+
64+
}

src/ServerlessWorkflow.Sdk.Builders/GenericTaskDefinitionBuilder.cs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,15 @@ public virtual ICallTaskDefinitionBuilder Call(string? function = null)
3333
return builder;
3434
}
3535

36+
/// <inheritdoc/>
37+
public virtual IDoTaskDefinitionBuilder Do(Action<ITaskDefinitionMapBuilder> setup)
38+
{
39+
var builder = new DoTaskDefinitionBuilder();
40+
builder.Do(setup);
41+
this.Builder = builder;
42+
return builder;
43+
}
44+
3645
/// <inheritdoc/>
3746
public virtual IEmitTaskDefinitionBuilder Emit(EventDefinition e)
3847
{
@@ -60,6 +69,14 @@ public virtual IForTaskDefinitionBuilder For()
6069
return builder;
6170
}
6271

72+
/// <inheritdoc/>
73+
public virtual IForkTaskDefinitionBuilder Fork()
74+
{
75+
var builder = new ForkTaskDefinitionBuilder();
76+
this.Builder = builder;
77+
return builder;
78+
}
79+
6380
/// <inheritdoc/>
6481
public virtual IListenTaskDefinitionBuilder Listen()
6582
{
@@ -69,9 +86,9 @@ public virtual IListenTaskDefinitionBuilder Listen()
6986
}
7087

7188
/// <inheritdoc/>
72-
public virtual ICompositeTaskDefinitionBuilder Execute()
89+
public virtual IDoTaskDefinitionBuilder Execute()
7390
{
74-
var builder = new CompositeTaskDefinitionBuilder();
91+
var builder = new DoTaskDefinitionBuilder();
7592
this.Builder = builder;
7693
return builder;
7794
}

src/ServerlessWorkflow.Sdk.Builders/Interfaces/ICompositeTaskDefinitionBuilder.cs renamed to src/ServerlessWorkflow.Sdk.Builders/Interfaces/IDoTaskDefinitionBuilder.cs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,17 @@
1414
namespace ServerlessWorkflow.Sdk.Builders;
1515

1616
/// <summary>
17-
/// Defines the fundamentals of a service used to build <see cref="CompositeTaskDefinition"/>s
17+
/// Defines the fundamentals of a service used to build <see cref="DoTaskDefinition"/>s
1818
/// </summary>
19-
public interface ICompositeTaskDefinitionBuilder
20-
: ITaskDefinitionBuilder<CompositeTaskDefinition>, ITaskExecutionStrategyDefinitionBuilder<ICompositeTaskDefinitionBuilder>
19+
public interface IDoTaskDefinitionBuilder
20+
: ITaskDefinitionBuilder<DoTaskDefinition>
2121
{
2222

23-
23+
/// <summary>
24+
/// Configures the tasks to perform sequentially
25+
/// </summary>
26+
/// <param name="setup">An <see cref="Action{T}"/> used to setup the tasks to perform sequentially</param>
27+
/// <returns>The configured <see cref="IDoTaskDefinitionBuilder"/></returns>
28+
IDoTaskDefinitionBuilder Do(Action<ITaskDefinitionMapBuilder> setup);
2429

2530
}

0 commit comments

Comments
 (0)