danielgerlag / danielgerlag/workflow-core

Strange behavior after Decide/Branch step - seems like interleaved execution

Open
#1,189 5 comments 0 reactions 0 assignees View on GitHub
Dominant language
C#
Stars
5.9k
Forks
1.3k
Avg merge
1d 1h
Merged PRs (30d)
5

Description

**Describe the bug**
If a workflow has steps after a Decide/Branch step then it seems that steps in branch and after the branch are executed interleaved

**To Reproduce**
Steps to reproduce the behavior:
Run this program:

```
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using WorkflowCore.Interface;
using WorkflowCore.Models;

namespace WorkflowCoreBranchProblem
{
internal class Program
{
static void Main(string[] args)
{
File.Delete(@"mydb.db");

var services = new ServiceCollection();
services.AddLogging(x => x.AddConsole());
services.AddTransient();
services.AddWorkflow(x => { x.UseSqlite("Data Source=mydb.db", true); });

var serviceProvider = services.BuildServiceProvider();
var host = serviceProvider.GetRequiredService();
host.RegisterWorkflow();
host.OnStepError += Host_OnStepError;
host.Start();

var workflowId = host.StartWorkflow("TestWorkflow", new TestWorkflowData());
Console.WriteLine($"Started workflow: {workflowId}");
Console.WriteLine("Press key to exit");
Console.ReadKey();
}

private static void Host_OnStepError(WorkflowInstance workflow, WorkflowStep step, Exception exception)
{
Console.WriteLine("Workflow Error: " + exception.Message);
}
}

class TestWorkflow : IWorkflow
{
public string Id => "TestWorkflow";
public int Version => 1;

public void Build(IWorkflowBuilder builder)
{
var branch1 = builder.CreateBranch()
.StartWith()
.Input(x => x.Number, x => 11)
.Then()
.Input(x => x.Number, x => 12)
.Then()
.Input(x => x.Number, x => 13)
.Then()
.Input(x => x.Number, x => 14)
.Then()
.Input(x => x.Number, x => 15);

var branch2 = builder.CreateBranch()
.StartWith()
.Input(x => x.Number, x => 21)
.Then()
.Input(x => x.Number, x => 22)
.Then()
.Input(x => x.Number, x => 23);

builder
.StartWith()
.Input(x => x.Number, x => 1)

.Then()
.Input(x => x.Number, x => 2)
.Output(x => x.Result, x => x.Result)

.Decide(data => data.Result)
.Branch((data, outcome) => data.Result == ResultType.Branch1, branch1)
.Branch((data, outcome) => data.Result == ResultType.Branch2, branch2)

.Then()
.Input(x => x.Number, x => 4)

.Then()
.Input(x => x.Number, x => 5);
}
}

class TestWorkflowData
{
public ResultType? Result { get; set; }
}

internal enum ResultType
{
Branch1,
Branch2
}

class LogStep : IStepBody
{
public int Number { get; set; }

public ResultType? Result { get; set; }

public async Task RunAsync(IStepExecutionContext context)
{
Console.WriteLine($"LogStep: {Number}");
Result = ResultType.Branch1;
return ExecutionResult.Next();
}
}
}
```

Output is:
LogStep: 1
LogStep: 2
LogStep: 11
LogStep: 4
LogStep: 12
LogStep: 5
LogStep: 13
LogStep: 14
LogStep: 15

**Expected behavior**
Output should be:
LogStep: 1
LogStep: 2
LogStep: 11
LogStep: 12
LogStep: 13
LogStep: 14
LogStep: 15
LogStep: 4
LogStep: 5

**Additional context**

- Is Decide/Branch supposed to be the last step in the workflow definition? I didn't find such information in the documentation [Decision Branches](https://workflow-core.readthedocs.io/en/latest/control-structures/#decision-branches)
- Are there any workarounds?

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.