-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #94 from danielgerlag/transaction-comensation-feature
Saga Transactions and compensation feature
- Loading branch information
Showing
67 changed files
with
2,151 additions
and
248 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
# Workflow Core 1.6.0 | ||
|
||
|
||
* Added Saga transaction feature | ||
* Added `.CompensateWith` feature | ||
|
||
|
||
#### Specifying compensation steps for each component of a saga transaction | ||
|
||
In this sample, if `Task2` throws an exception, then `UndoTask2` and `UndoTask1` will be triggered. | ||
|
||
```c# | ||
builder | ||
.StartWith<SayHello>() | ||
.CompensateWith<UndoHello>() | ||
.Saga(saga => saga | ||
.StartWith<DoTask1>() | ||
.CompensateWith<UndoTask1>() | ||
.Then<DoTask2>() | ||
.CompensateWith<UndoTask2>() | ||
.Then<DoTask3>() | ||
.CompensateWith<UndoTask3>() | ||
) | ||
.Then<SayGoodbye>(); | ||
``` | ||
|
||
#### Retrying a failed transaction | ||
|
||
This particular example will retry the entire saga every 5 seconds | ||
|
||
```c# | ||
builder | ||
.StartWith<SayHello>() | ||
.CompensateWith<UndoHello>() | ||
.Saga(saga => saga | ||
.StartWith<DoTask1>() | ||
.CompensateWith<UndoTask1>() | ||
.Then<DoTask2>() | ||
.CompensateWith<UndoTask2>() | ||
.Then<DoTask3>() | ||
.CompensateWith<UndoTask3>() | ||
) | ||
.OnError(Models.WorkflowErrorHandling.Retry, TimeSpan.FromSeconds(5)) | ||
.Then<SayGoodbye>(); | ||
``` | ||
|
||
#### Compensating the entire transaction | ||
|
||
You could also only specify a master compensation step, as follows | ||
|
||
```c# | ||
builder | ||
.StartWith<SayHello>() | ||
.CompensateWith<UndoHello>() | ||
.Saga(saga => saga | ||
.StartWith<DoTask1>() | ||
.Then<DoTask2>() | ||
.Then<DoTask3>() | ||
) | ||
.CompensateWithSequence(comp => comp | ||
.StartWith<UndoTask1>() | ||
.Then<UndoTask2>() | ||
.Then<UndoTask3>() | ||
) | ||
.Then<SayGoodbye>(); | ||
``` | ||
|
||
#### Passing parameters | ||
|
||
Parameters can be passed to a compensation step as follows | ||
|
||
```c# | ||
builder | ||
.StartWith<SayHello>() | ||
.CompensateWith<PrintMessage>(compensate => | ||
{ | ||
compensate.Input(step => step.Message, data => "undoing..."); | ||
}) | ||
``` | ||
|
||
|
||
### Expressing a saga in JSON | ||
|
||
A saga transaction can be expressed in JSON, by using the `WorkflowCore.Primitives.Sequence` step and setting the `Saga` parameter to `true`. | ||
|
||
The compensation steps can be defined by specifying the `CompensateWith` parameter. | ||
|
||
```json | ||
{ | ||
"Id": "Saga-Sample", | ||
"Version": 1, | ||
"DataType": "MyApp.MyDataClass, MyApp", | ||
"Steps": [ | ||
{ | ||
"Id": "Hello", | ||
"StepType": "MyApp.HelloWorld, MyApp", | ||
"NextStepId": "MySaga" | ||
}, | ||
{ | ||
"Id": "MySaga", | ||
"StepType": "WorkflowCore.Primitives.Sequence, WorkflowCore", | ||
"NextStepId": "Bye", | ||
"Saga": true, | ||
"Do": [ | ||
[ | ||
{ | ||
"Id": "do1", | ||
"StepType": "MyApp.Task1, MyApp", | ||
"NextStepId": "do2", | ||
"CompensateWith": [ | ||
{ | ||
"Id": "undo1", | ||
"StepType": "MyApp.UndoTask1, MyApp" | ||
} | ||
] | ||
}, | ||
{ | ||
"Id": "do2", | ||
"StepType": "MyApp.Task2, MyApp", | ||
"CompensateWith": [ | ||
{ | ||
"Id": "undo2-1", | ||
"NextStepId": "undo2-2", | ||
"StepType": "MyApp.UndoTask2, MyApp" | ||
}, | ||
{ | ||
"Id": "undo2-2", | ||
"StepType": "MyApp.DoSomethingElse, MyApp" | ||
} | ||
] | ||
} | ||
] | ||
] | ||
}, | ||
{ | ||
"Id": "Bye", | ||
"StepType": "MyApp.GoodbyeWorld, MyApp" | ||
} | ||
] | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
using WorkflowCore.Models; | ||
|
||
namespace WorkflowCore.Interface | ||
{ | ||
public interface IExecutionPointerFactory | ||
{ | ||
ExecutionPointer BuildStartingPointer(WorkflowDefinition def); | ||
ExecutionPointer BuildCompensationPointer(WorkflowDefinition def, ExecutionPointer pointer, ExecutionPointer exceptionPointer, int compensationStepId); | ||
ExecutionPointer BuildNextPointer(WorkflowDefinition def, ExecutionPointer pointer, StepOutcome outcomeTarget); | ||
ExecutionPointer BuildChildPointer(WorkflowDefinition def, ExecutionPointer pointer, int childDefinitionId, object branch); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
using System; | ||
using WorkflowCore.Models; | ||
|
||
namespace WorkflowCore.Interface | ||
{ | ||
public interface IExecutionResultProcessor | ||
{ | ||
void HandleStepException(WorkflowInstance workflow, WorkflowDefinition def, ExecutionPointer pointer, WorkflowStep step); | ||
void ProcessExecutionResult(WorkflowInstance workflow, WorkflowDefinition def, ExecutionPointer pointer, WorkflowStep step, ExecutionResult result, WorkflowExecutorResult workflowResult); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -26,6 +26,7 @@ public enum WorkflowErrorHandling | |
{ | ||
Retry = 0, | ||
Suspend = 1, | ||
Terminate = 2 | ||
Terminate = 2, | ||
Compensate = 3 | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.