ActorSrcGen 0.2.10

There is a newer version of this package available.
See the version list below for details.
The owner has unlisted this package. This could mean that the package is deprecated, has security vulnerabilities or shouldn't be used anymore.
dotnet add package ActorSrcGen --version 0.2.10
NuGet\Install-Package ActorSrcGen -Version 0.2.10
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="ActorSrcGen" Version="0.2.10" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add ActorSrcGen --version 0.2.10
#r "nuget: ActorSrcGen, 0.2.10"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install ActorSrcGen as a Cake Addin
#addin nuget:?package=ActorSrcGen&version=0.2.10

// Install ActorSrcGen as a Cake Tool
#tool nuget:?package=ActorSrcGen&version=0.2.10

Welcome to ActorSrcGen

ActorSrcGen is a C# Source Generator allowing the conversion of simple C# classes into Dataflow compatible pipelines supporting the actor model.

Where to get it

The source generator can be installed using nuget at ActorSrcGen.

NB. This library is only days old, and will probably change significantly in the weeks ahead. Please treat it as experimental for the time being.

If you notice any issues with the generated code please report them on Github.

What it does

The aim of the source generator is to help you simplify your code. It does that by generating the boilerplate code needed to use TPL Dataflow with a regular class. So you write a simple partial class like this:

[Actor]
public partial class MyWorkflow
{
    [InitialStep(next: "DoTask2")]
    public Task<string> DoTask1(int x)
    {
        Console.WriteLine("DoTask1");
        return Task.FromResult(x.ToString());
    }

    [Step(next: "DoTask3")]
    public Task<string> DoTask2(string x)
    {
        Console.WriteLine("DoTask2");
        return Task.FromResult($"100{x}");
    }

    [LastStep]
    public Task<int> DoTask3(string input)
    {
        Console.WriteLine("DoTask3");
        return Task.FromResult(int.Parse(input));
    }
}

And the source generator will extend it, adding the TPL Dataflow code to wire the methods together:

namespace ActorSrcGen.Abstractions.Playground;
using System.Threading.Tasks.Dataflow;
using Gridsum.DataflowEx;

public partial class MyWorkflow : Dataflow<Int32, Int32>
{
    public MyWorkflow() : base(DataflowOptions.Default)
    {
        _DoTask1 = new TransformManyBlock<Int32, String>(async (Int32 x) => {
            var result = new List<String>();
            try
            {
                result.Add(await DoTask1(x));
            }catch{}
            return result;
        },
            new ExecutionDataflowBlockOptions() {
                BoundedCapacity = 5,
                MaxDegreeOfParallelism = 8
        });
        RegisterChild(_DoTask1);
        _DoTask2 = new TransformManyBlock<String, String>(async (String x) => {
            var result = new List<String>();
            try
            {
                result.Add(await DoTask2(x));
            }catch{}
            return result;
        },
            new ExecutionDataflowBlockOptions() {
                BoundedCapacity = 5,
                MaxDegreeOfParallelism = 8
        });
        RegisterChild(_DoTask2);
        _DoTask3 = new TransformManyBlock<String, Int32>(async (String x) => {
            var result = new List<Int32>();
            try
            {
                result.Add(await DoTask3(x));
            }catch{}
            return result;
        },
            new ExecutionDataflowBlockOptions() {
                BoundedCapacity = 5,
                MaxDegreeOfParallelism = 8
        });
        RegisterChild(_DoTask3);
        _DoTask1.LinkTo(_DoTask2, new DataflowLinkOptions { PropagateCompletion = true });
        _DoTask2.LinkTo(_DoTask3, new DataflowLinkOptions { PropagateCompletion = true });
    }
    TransformManyBlock<Int32, String> _DoTask1;

    TransformManyBlock<String, String> _DoTask2;

    TransformManyBlock<String, Int32> _DoTask3;

    public override ITargetBlock<Int32> InputBlock { get => _DoTask1; }
    public override ISourceBlock<Int32> OutputBlock { get => _DoTask3; }

    public async Task<bool> Post(Int32 input)
    => await InputBlock.SendAsync(input);
} 

Invocation of your class is a straightforward call to post a message to it:

using ActorSrcGen.Abstractions.Playground;

var wf = new MyWorkflow();
if (await wf.Cast(10))
    Console.WriteLine("Called Asynchronously");

var wf2 = new MyWorkflow2();
if (wf2.Call(10))
    Console.WriteLine("Called Synchronously");

await wf2.CompletionTask;

Why Bother?

Writing robust and performant asynchronous and concurrent code in .NET is a laborious process. TPL Dataflow makes it easier - it "provides dataflow components to help increase the robustness of concurrency-enabled applications. This dataflow model promotes actor-based programming by providing in-process message passing for coarse-grained dataflow and pipelining tasks" (see docs). This source generator allows you to take advantage of that model without needing to write a lot of the necessary boilerplate code.

The generated source builds atop DataflowEx for a clean stateful object-oriented wrapper around your pipeline.

With thanks to:

There are no supported framework assets in this package.

Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last updated
1.1.2 67 5/9/2024
1.1.1 66 5/8/2024
1.0.3 92 4/29/2024
1.0.2 81 4/29/2024