Skip to content

Commit 4378cca

Browse files
authored
Merge pull request danielgerlag#192 from danielgerlag/issue-191
Order of compensation steps
2 parents 29600de + ecd3d73 commit 4378cca

File tree

5 files changed

+95
-4
lines changed

5 files changed

+95
-4
lines changed

ReleaseNotes/1.6.8.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Workflow Core 1.6.8
2+
3+
* Fixed the order in which multiple compensating steps execute within a saga transaction. [Issue 191](https://github.com/danielgerlag/workflow-core/issues/191)

WorkflowCore.sln

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ReleaseNotes", "ReleaseNote
9292
ReleaseNotes\1.4.0.md = ReleaseNotes\1.4.0.md
9393
ReleaseNotes\1.6.0.md = ReleaseNotes\1.6.0.md
9494
ReleaseNotes\1.6.6.md = ReleaseNotes\1.6.6.md
95+
ReleaseNotes\1.6.8.md = ReleaseNotes\1.6.8.md
9596
EndProjectSection
9697
EndProject
9798
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WorkflowCore.Sample14", "src\samples\WorkflowCore.Sample14\WorkflowCore.Sample14.csproj", "{6BC66637-B42A-4334-ADFB-DBEC9F29D293}"

src/WorkflowCore/Services/ExecutionResultProcessor.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,11 @@ private void Compensate(WorkflowInstance workflow, WorkflowDefinition def, Execu
152152

153153
if (revert)
154154
{
155-
var prevSiblings = workflow.ExecutionPointers.Where(x => pointer.Scope.SequenceEqual(x.Scope) && x.Id != pointer.Id && x.Status == PointerStatus.Complete).ToList();
155+
var prevSiblings = workflow.ExecutionPointers
156+
.Where(x => pointer.Scope.SequenceEqual(x.Scope) && x.Id != pointer.Id && x.Status == PointerStatus.Complete)
157+
.OrderByDescending(x => x.EndTime)
158+
.ToList();
159+
156160
foreach (var siblingPointer in prevSiblings)
157161
{
158162
var siblingStep = def.Steps.First(x => x.Id == siblingPointer.StepId);

src/WorkflowCore/WorkflowCore.csproj

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@
1515
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
1616
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
1717
<Description>Workflow Core is a light weight workflow engine targeting .NET Standard.</Description>
18-
<Version>1.6.7</Version>
19-
<AssemblyVersion>1.6.7.0</AssemblyVersion>
20-
<FileVersion>1.6.7.0</FileVersion>
18+
<Version>1.6.8</Version>
19+
<AssemblyVersion>1.6.8.0</AssemblyVersion>
20+
<FileVersion>1.6.8.0</FileVersion>
2121
<PackageReleaseNotes></PackageReleaseNotes>
2222
<PackageIconUrl>https://github.com/danielgerlag/workflow-core/raw/master/src/logo.png</PackageIconUrl>
2323
</PropertyGroup>
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
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 MultistepCompensationScenario : WorkflowTest<MultistepCompensationScenario.Workflow, Object>
14+
{
15+
public class Workflow : IWorkflow
16+
{
17+
public static int Compensation1Fired = -1;
18+
public static int Compensation2Fired = -1;
19+
public static int Compensation3Fired = -1;
20+
public static int Compensation4Fired = -1;
21+
public static int CompensationCounter = 0;
22+
23+
public string Id => "CompensatingWorkflow";
24+
public int Version => 1;
25+
public void Build(IWorkflowBuilder<object> builder)
26+
{
27+
builder
28+
.StartWith(context => ExecutionResult.Next())
29+
.Saga(x => x
30+
.StartWith(context => ExecutionResult.Next())
31+
.CompensateWith(context =>
32+
{
33+
CompensationCounter++;
34+
Compensation1Fired = CompensationCounter;
35+
})
36+
.Then(context => ExecutionResult.Next())
37+
.CompensateWith(context =>
38+
{
39+
CompensationCounter++;
40+
Compensation2Fired = CompensationCounter;
41+
})
42+
.Then(context => ExecutionResult.Next())
43+
.CompensateWith(context =>
44+
{
45+
CompensationCounter++;
46+
Compensation3Fired = CompensationCounter;
47+
})
48+
.Then(context => throw new Exception())
49+
.CompensateWith(context =>
50+
{
51+
CompensationCounter++;
52+
Compensation4Fired = CompensationCounter;
53+
})
54+
);
55+
}
56+
}
57+
58+
public MultistepCompensationScenario()
59+
{
60+
Setup();
61+
Workflow.Compensation1Fired = -1;
62+
Workflow.Compensation2Fired = -1;
63+
Workflow.Compensation3Fired = -1;
64+
Workflow.Compensation4Fired = -1;
65+
Workflow.CompensationCounter = 0;
66+
}
67+
68+
[Fact]
69+
public void MultiCompensationStepOrder()
70+
{
71+
var workflowId = StartWorkflow(null);
72+
WaitForWorkflowToComplete(workflowId, TimeSpan.FromSeconds(30));
73+
74+
GetStatus(workflowId).Should().Be(WorkflowStatus.Complete);
75+
UnhandledStepErrors.Count.Should().Be(1);
76+
77+
Workflow.Compensation1Fired.Should().Be(4);
78+
Workflow.Compensation2Fired.Should().Be(3);
79+
Workflow.Compensation3Fired.Should().Be(2);
80+
Workflow.Compensation4Fired.Should().Be(1);
81+
}
82+
}
83+
}

0 commit comments

Comments
 (0)