Skip to content

Commit

Permalink
Merge pull request #30 from kbilsted/v1.5.1
Browse files Browse the repository at this point in the history
V1.5.1
  • Loading branch information
kbilsted authored Dec 17, 2024
2 parents f1f193c + ad5e281 commit 03ec21f
Show file tree
Hide file tree
Showing 12 changed files with 402 additions and 45 deletions.
34 changes: 19 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
# Micro Workflow .net
<!--start-->
[![Stats](https://img.shields.io/badge/Code_lines-1,7_K-ff69b4.svg)]()
[![Stats](https://img.shields.io/badge/Code_lines-1,8_K-ff69b4.svg)]()
[![Stats](https://img.shields.io/badge/Test_lines-1,2_K-69ffb4.svg)]()
[![Stats](https://img.shields.io/badge/Doc_lines-594-ffb469.svg)]()
[![Stats](https://img.shields.io/badge/Doc_lines-936-ffb469.svg)]()
<!--end-->


<p align="center"> <img src="doc/microworkflow.webp" alt="logo"></p>

Micro Workflow is a very fast, small, embedable and distributed workflow system primarily for .Net developers.
Expand All @@ -14,22 +13,27 @@ The code base is so small every one can read and understand the inner workings i

# 1. Why use Micro Workflow

You should consider using Micro Workflow due to one or more of the following reason
You should consider using Micro Workflow for one or more of the following reasons.
* When you have a need for a queue,
* scheduling and re-scheduling of code to be executed
* distributing load across multiple servers
* or a business process that needs to be robust (have it being broken up into steps and its progress persisted).

when you have a need for a queue, scheduling of code to execute, or a business process that needs to be robus. We provide many examples in ["integration patterns"](https://github.com/kbilsted/MicroWorkflow.net/tree/feature/doc?tab=readme-ov-file#5-integration-patterns)
We provide many examples in ["integration patterns"](https://github.com/kbilsted/MicroWorkflow.net/tree/feature/doc?tab=readme-ov-file#5-integration-patterns) on how to get started.

Design philosophy

**Simplicity**
* We model only the steps in a workflow, *not* the transitions between them
* This greatly *simplify* the model, the versioning of flows and steps
* enable you to use reusable code blocks for determining a transition
* It is *easy* to embed it directly into your solutions to improve resiliance or use as a stand-alone workflow
* This greatly *simplifies* the model, especially when dealing with change and versioning
* It enables you to use reusable code blocks for determining a transition
* It is *easy* to embed micro workflow directly into your solutions to improve resiliance or use as a stand-alone workflow

**We use C# all the way**
* We don't want to invent a new language - we love C#!
* We don't want to invent a new language for the workflow - we love C#!
* Workflow code is *readable*, *debugable*, and *testable* - like the rest of your code base.
* You can use existing best practices for logging, IOC containers etc. of your choice
* Since Workflow code is just C# it is *easy to commit and merge* use your existing *branching strategies*
* Workflow code is just C# so it is *easy to commit and merge* using your existing *branching strategies*
* You *do not* need a special graphical editor for specifying flows

**The datamodel is simple - just three DB tables**
Expand All @@ -38,15 +42,15 @@ when you have a need for a queue, scheduling of code to execute, or a business p

**Distributed mindset**
* Supports *Fail-over setup* To improve up-time applications/integrations are often running on multiple servers at the same time. This is a common scenario is supported with no special setup.
* Supports incremental deployments across more instances. When deploying multiple instances, the roll-out is typical gradual. Hence we support that steps may be added that is only known to a sub-set of the running workflows.
* Supports incremental deployments across multiple instances, meaning the roll-out is gradual. Hence we support that steps may be added that is only known to a sub-set of the running workflows.

**Scalable**
* You can add more workers in the workflow engine (vertical scaling)
* You can add more servers each running a workflow engine (horizontal scaling)

**No external dependencies**
* The core library has *no external dependencies*, you can use whatever database, logger, json/xml/binary serializer you want ... in any version you want
* Convenience supplement nuget packages for Newtonsoft json, Ado .net, and Autofac are provided
* To get you quickly started, we supply nuget packages for "Newtonsoft Json", "Ado .Net Db", and "Autofac IOC". The packages are completely optional.


# 2. Overview
Expand All @@ -61,11 +65,11 @@ Supported scalabilities

# 3. Getting started

To define a workflow with the two steps `FetchData` (which fetches some data), and `AnalyzeWords` (that analyzes the data), we implement interface `IStepImplementation` twice.
To transition from one step to one (or several steps), use `Done()`. This tells the engine that the current step has finished sucesfully. You can supply one or more steps that will be executed in the future.
To define a workflow with the two steps, a `FetchData` step that fetches some data, and a `AnalyzeWords` step that analyzes the data, we implement interface `IStepImplementation` twice.
To transition from one step to another, the step uses `return Done()`. This tells the engine that the current step has finished sucesfully. You can supply one or more steps that will be executed as a result of the success.
This is how you control ordering of events.

There are no restrictions on the names of steps, but we found using a scheme similar to REST api's is beneficial. Hence we recommend you to use `{version}/{business domain}/{workflow name}/{workflow step}`.
There are no restrictions on the names of steps, but we found using a scheme similar to REST api's to be beneficial. Hence using the following format `{version}/{business domain}/{workflow name}/{workflow step}`. By defining the name of the flow as a `public const` it is easy to "find usage" inside the code base and to ensure no mis-spelling. Two workflow steps cannot have the same name.

```C#
[StepName(Name)]
Expand Down
2 changes: 1 addition & 1 deletion src/Demos/ConsoleDemo/MicroWorkflow.ConsoleDemo.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Autofac" Version="8.0.0" />
<PackageReference Include="Autofac" Version="8.1.1" />
</ItemGroup>

<ItemGroup>
Expand Down
13 changes: 7 additions & 6 deletions src/Demos/MicroWorkflow.Tests/AdoSingletonStepTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ public void When_creating_a_singleton_Then_it_is_created()
Singleton = true,
FlowId = helper.FlowId
}];
helper.StepHandlers = [Handle(name, step => {
helper.StepHandlers = [Handle(name, step => {
stepResult = $"hello";
stepResultIsSingleton = step.Singleton;
return step.Done();
return step.Done();
})];
helper.StopWhenNoWork().BuildAndStart();

Expand Down Expand Up @@ -74,13 +74,14 @@ public void When_AddStepIfNotExists_two_identical_singleton_steps_Then_insert_fi
var name = helper.RndName;
var step = new Step(name) { Singleton = true };
SearchModel searchModel = new(Name: step.Name);
engine.Data.AddStepIfNotExists(step, searchModel)
.Should()

var id = engine.Data.AddStepIfNotExists(step, searchModel);
id.Should()
.HaveValue();

var step2 = new Step(name) { Singleton = true };
engine.Data.AddStepIfNotExists(step2, searchModel)
.Should()
id = engine.Data.AddStepIfNotExists(step2, searchModel);
id.Should()
.BeNull();
}
}
4 changes: 2 additions & 2 deletions src/Demos/MicroWorkflow.Tests/DocumentationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public async Task<ExecutionResult> ExecuteAsync(Step step)

// ... stuff

return step.Done();
return await Task.FromResult(step.Done());
}
}

Expand All @@ -82,7 +82,7 @@ public async Task<ExecutionResult> ExecuteAsync(Step step)

// ... fetch data

return step.Rerun(scheduleTime: step.ExecutionStartTime!.Value.AddHours(1));
return await Task.FromResult(step.Rerun(scheduleTime: step.ExecutionStartTime!.Value.AddHours(1)));
}
}

Expand Down
15 changes: 5 additions & 10 deletions src/Demos/MicroWorkflow.Tests/MicroWorkflow.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,12 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Autofac" Version="8.0.0" />
<PackageReference Include="AutoFixture" Version="4.18.1" />
<PackageReference Include="FluentAssertions" Version="6.12.0" />
<PackageReference Include="Autofac" Version="8.1.1" />
<PackageReference Include="FluentAssertions" Version="7.0.0" />
<PackageReference Include="LineCounter" Version="1.1.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
<PackageReference Include="NUnit" Version="4.1.0" />
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0" />
<PackageReference Include="coverlet.collector" Version="6.0.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<PackageReference Include="NUnit" Version="4.3.0" />
<PackageReference Include="NUnit3TestAdapter" Version="4.6.0" />
<PackageReference Include="ReassureTest" Version="0.8.0" />
</ItemGroup>

Expand Down
1 change: 1 addition & 0 deletions src/Demos/MicroWorkflow.Tests/PerformanceTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

namespace MicroWorkflow;

[Explicit("slow")]
public class PerformanceTests
{
[Test]
Expand Down
6 changes: 3 additions & 3 deletions src/Demos/WebApiDemo/MicroWorkflow.WebApiDemo.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Autofac" Version="8.0.0" />
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="9.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
<PackageReference Include="Autofac" Version="8.1.1" />
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="10.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.8.1" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Data.SqlClient" Version="5.1.5" />
<PackageReference Include="Microsoft.Data.SqlClient" Version="5.2.2" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Autofac" Version="8.0.0" />
<PackageReference Include="Autofac" Version="8.1.1" />
<ProjectReference Include="..\MicroWorkflow\MicroWorkflow.csproj" />

</ItemGroup>
Expand Down
Loading

0 comments on commit 03ec21f

Please sign in to comment.