Skip to content

Releases: danielgerlag/workflow-core

v3.2

08 Aug 15:52
Compare
Choose a tag to compare

Workflow Core 3.2

  • Option to run foreach in non-parallel mode #597
  • StartWith no longer required #598
  • Concurrency issue #608
  • Option to auto-delete complete workflows on redis #613

v3.1.0

05 Jan 16:23
effdd02
Compare
Choose a tag to compare

Workflow Core 3.1.0

Decision Branching

You can define multiple independent branches within your workflow and select one based on an expression value.

For the fluent API, we define our branches with the CreateBranch() method on the workflow builder. We can then select a branch using the Branch method.

The select expressions will be matched to the branch listed via the Branch method, and the matching next step(s) will be scheduled to execute next.

This workflow will select branch1 if the value of data.Value1 is one, and branch2 if it is two.

var branch1 = builder.CreateBranch()
    .StartWith<PrintMessage>()
        .Input(step => step.Message, data => "hi from 1")
    .Then<PrintMessage>()
        .Input(step => step.Message, data => "bye from 1");

var branch2 = builder.CreateBranch()
    .StartWith<PrintMessage>()
        .Input(step => step.Message, data => "hi from 2")
    .Then<PrintMessage>()
        .Input(step => step.Message, data => "bye from 2");


builder
    .StartWith<HelloWorld>()
    .Decide(data => data.Value1)
        .Branch((data, outcome) => data.Value1 == "one", branch1)
        .Branch((data, outcome) => data.Value1 == "two", branch2);

The JSON representation would look somthing like this.

{
  "Id": "DecisionWorkflow",
  "Version": 1,
  "DataType": "MyApp.MyData, MyApp",
  "Steps": [
    {
      "Id": "decide",
      "StepType": "...",
      "SelectNextStep":
      {
        "Print1": "data.Value1 == \"one\"",
        "Print2": "data.Value1 == \"two\""
      }
    },
    {
      "Id": "Print1",
      "StepType": "MyApp.PrintMessage, MyApp",
      "Inputs": 
	  { 
		"Message": "\"Hello from 1\"" 
	  }
    },
    {
      "Id": "Print2",
      "StepType": "MyApp.PrintMessage, MyApp",
      "Inputs": 
	  { 
	    "Message": "\"Hello from 2\"" 
	  }
    }
  ]
}

Outcomes for JSON workflows

You can now specify OutcomeSteps for a step in JSON and YAML workflow definitions.

"SelectNextStep":
{
	"<<Step1 Id>>": "<<expression>>",
	"<<Step2 Id>>": "<<expression>>"
}

If the outcome of a step matches a particular expression, that step would be scheduled as the next step to execute.

v3.0.0

22 Dec 17:22
a93bdd0
Compare
Choose a tag to compare

Workflow Core 3.0.0

Support for PostgeSQL is delayed because of this issue with upstream libraries

Split DSL into own package

The JSON and YAML definition features into their own package.

Migration required for existing projects:

  • Install the WorkflowCore.DSL package from nuget.
  • Call AddWorkflowDSL() on your service collection.

Activities

An activity is defined as an item on an external queue of work, that a workflow can wait for.

In this example the workflow will wait for activity-1, before proceeding. It also passes the value of data.Value1 to the activity, it then maps the result of the activity to data.Value2.

Then we create a worker to process the queue of activity items. It uses the GetPendingActivity method to get an activity and the data that a workflow is waiting for.

public class ActivityWorkflow : IWorkflow<MyData>
{
    public void Build(IWorkflowBuilder<MyData> builder)
    {
        builder                
            .StartWith<HelloWorld>()
            .Activity("activity-1", (data) => data.Value1)
                .Output(data => data.Value2, step => step.Result)
            .Then<PrintMessage>()
                .Input(step => step.Message, data => data.Value2);
    }
             
}
...

var activity = host.GetPendingActivity("activity-1", "worker1", TimeSpan.FromMinutes(1)).Result;

if (activity != null)
{
    Console.WriteLine(activity.Parameters);
    host.SubmitActivitySuccess(activity.Token, "Some response data");
}

The JSON representation of this step would look like this

{
    "Id": "activity-step",
    "StepType": "WorkflowCore.Primitives.Activity, WorkflowCore",
    "Inputs": 
    {
        "ActivityName": "\"activity-1\"",
        "Parameters": "data.Value1" 
    },
    "Outputs": { "Value2": "step.Result" }
}

v2.1.2

06 Oct 23:47
3efd085
Compare
Choose a tag to compare

Workflow Core 2.1.2

  • Adds a feature to purge old workflows from the persistence store.

New IWorkflowPurger service that can be injected from the IoC container

Task PurgeWorkflows(WorkflowStatus status, DateTime olderThan)

Implementations are currently only for SQL Server, Postgres and MongoDB

v2.1.0

15 Sep 19:01
Compare
Choose a tag to compare

Workflow Core 2.1.0

  • Adds the SyncWorkflowRunner service that enables workflows to be executed synchronously, you can also avoid persisting the state to the persistence store entirely

usage

var runner = serviceProvider.GetService<ISyncWorkflowRunner>();
...
var worfklow = await runner.RunWorkflowSync("my-workflow", 1, data, TimeSpan.FromSeconds(10));

v2.0.0

30 Jun 13:56
c182dce
Compare
Choose a tag to compare

Workflow Core 2.0.0

Upgrade notes

Existing JSON definitions will be loaded as follows

using WorkflowCore.Services.DefinitionStorage;
...
DefinitionLoader.LoadDefinition(json, Deserializers.Json);
  • Targets .NET Standard 2.0

    The core library now targets .NET Standard 2.0, in order to leverage newer features.

  • Support for YAML definitions

    Added support for YAML workflow definitions, which can be loaded as follows

    using WorkflowCore.Services.DefinitionStorage;
    ...
    DefinitionLoader.LoadDefinition(json, Deserializers.Yaml);

    Existing JSON definitions will be loaded as follows

    using WorkflowCore.Services.DefinitionStorage;
    ...
    DefinitionLoader.LoadDefinition(json, Deserializers.Json);
  • Object graphs and inline expressions on input properties

    You can now pass object graphs to step inputs as opposed to just scalar values

    "inputs": 
    {    
      "Body": {
          "Value1": 1,
          "Value2": 2
      },
      "Headers": {
          "Content-Type": "application/json"
      }
    },
    

    If you want to evaluate an expression for a given property of your object, simply prepend and @ and pass an expression string

    "inputs": 
    {    
      "Body": {
          "@Value1": "data.MyValue * 2",
          "Value2": 5
      },
      "Headers": {
          "Content-Type": "application/json"
      }
    },
    
  • Support for enum values on input properties

    If your step has an enum property, you can now just pass the string representation of the enum value and it will be automatically converted.

  • Environment variables available in input expressions

    You can now access environment variables from within input expressions.
    usage:

    environment["VARIABLE_NAME"]
    

v1.9.3

07 Apr 15:51
Compare
Choose a tag to compare

Workflow Core 1.9.3

  • Fixes the order of processing for multiple events with same name/key
  • Adds UseMaxConcurrentWorkflows to WorkflowOptions to allow overriding the max number of concurrent workflows for a given node

v1.9.2

31 Mar 14:40
Compare
Choose a tag to compare

Workflow Core 1.9.2

Changes the default retry behavior for steps within a saga to bubble up to the saga container.
This means you do not have to explicitly set each step within the saga to Compensate.

v1.8.3

24 Feb 16:01
b4cba8d
Compare
Choose a tag to compare
  • Added Attach and Id to fluent API
    This will enable one to attach the flow from a step to any other step with an Id
    Control structure scope will be preserved
      .StartWith<Step1>()
          .Id("step1")
      .Then<Step2>()
      .Attach("step1")    
  • Added index queue ahead of upcoming feature for async indexing
  • Various performance improvements

v1.8.1

03 Feb 16:17
Compare
Choose a tag to compare

Workflow Core 1.8.1

Thank you to @MarioAndron

This release adds a feature where a DI scope is created around the construction of steps that are registered with your IoC container.

This enables steps to consume services registered as scoped.