Skip to content

Commit 3b74e77

Browse files
authored
Default retry behavior inside saga (danielgerlag#295)
1 parent cf002b8 commit 3b74e77

File tree

3 files changed

+72
-7
lines changed

3 files changed

+72
-7
lines changed

src/WorkflowCore/Services/ExecutionResultProcessor.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,8 @@ public void HandleStepException(WorkflowInstance workflow, WorkflowDefinition de
110110
{
111111
var exceptionPointer = queue.Dequeue();
112112
var exceptionStep = def.Steps.FindById(exceptionPointer.StepId);
113-
var compensatingStepId = FindScopeCompensationStepId(workflow, def, exceptionPointer);
114-
var errorOption = (exceptionStep.ErrorBehavior ?? (compensatingStepId.HasValue ? WorkflowErrorHandling.Compensate : def.DefaultErrorBehavior));
113+
var shouldCompensate = ShouldCompensate(workflow, def, exceptionPointer);
114+
var errorOption = (exceptionStep.ErrorBehavior ?? (shouldCompensate ? WorkflowErrorHandling.Compensate : def.DefaultErrorBehavior));
115115

116116
foreach (var handler in _errorHandlers.Where(x => x.Type == errorOption))
117117
{
@@ -120,7 +120,7 @@ public void HandleStepException(WorkflowInstance workflow, WorkflowDefinition de
120120
}
121121
}
122122

123-
private int? FindScopeCompensationStepId(WorkflowInstance workflow, WorkflowDefinition def, ExecutionPointer currentPointer)
123+
private bool ShouldCompensate(WorkflowInstance workflow, WorkflowDefinition def, ExecutionPointer currentPointer)
124124
{
125125
var scope = new Stack<string>(currentPointer.Scope);
126126
scope.Push(currentPointer.Id);
@@ -130,11 +130,11 @@ public void HandleStepException(WorkflowInstance workflow, WorkflowDefinition de
130130
var pointerId = scope.Pop();
131131
var pointer = workflow.ExecutionPointers.FindById(pointerId);
132132
var step = def.Steps.FindById(pointer.StepId);
133-
if (step.CompensationStepId.HasValue)
134-
return step.CompensationStepId.Value;
133+
if ((step.CompensationStepId.HasValue) || (step.RevertChildrenAfterCompensation))
134+
return true;
135135
}
136136

137-
return null;
137+
return false;
138138
}
139139
}
140140
}

test/WorkflowCore.IntegrationTests/Scenarios/DynamicDataIOScenario.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public int this[string propertyName]
3838

3939
public class DataIOWorkflow : IWorkflow<MyDataClass>
4040
{
41-
public string Id => "DataIOWorkflow";
41+
public string Id => "DynamicDataIOWorkflow";
4242
public int Version => 1;
4343
public void Build(IWorkflowBuilder<MyDataClass> builder)
4444
{
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
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 FailingSagaScenario : WorkflowTest<FailingSagaScenario.Workflow, object>
14+
{
15+
public class Workflow : IWorkflow<object>
16+
{
17+
public static int Event1Fired;
18+
public static int Event2Fired;
19+
public static int Event3Fired;
20+
21+
public string Id => "NestedRetrySaga2Workflow";
22+
public int Version => 1;
23+
public void Build(IWorkflowBuilder<object> builder)
24+
{
25+
builder
26+
.StartWith(context => ExecutionResult.Next())
27+
.Saga(x => x
28+
.StartWith(context => ExecutionResult.Next())
29+
.If(data => true)
30+
.Do(i => i
31+
.StartWith(context =>
32+
{
33+
Event1Fired++;
34+
throw new Exception();
35+
})
36+
)
37+
.Then(context => Event2Fired++)
38+
)
39+
.OnError(WorkflowErrorHandling.Terminate)
40+
.Then(context => Event3Fired++);
41+
}
42+
}
43+
44+
public FailingSagaScenario()
45+
{
46+
Setup();
47+
Workflow.Event1Fired = 0;
48+
Workflow.Event2Fired = 0;
49+
Workflow.Event3Fired = 0;
50+
}
51+
52+
[Fact]
53+
public void Scenario()
54+
{
55+
var workflowId = StartWorkflow(null);
56+
WaitForWorkflowToComplete(workflowId, TimeSpan.FromSeconds(30));
57+
58+
GetStatus(workflowId).Should().Be(WorkflowStatus.Terminated);
59+
UnhandledStepErrors.Count.Should().Be(1);
60+
Workflow.Event1Fired.Should().Be(1);
61+
Workflow.Event2Fired.Should().Be(0);
62+
Workflow.Event3Fired.Should().Be(0);
63+
}
64+
}
65+
}

0 commit comments

Comments
 (0)