conductor-csharp 0.0.3

There is a newer version of this package available.
See the version list below for details.
dotnet add package conductor-csharp --version 0.0.3                
NuGet\Install-Package conductor-csharp -Version 0.0.3                
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="conductor-csharp" Version="0.0.3" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add conductor-csharp --version 0.0.3                
#r "nuget: conductor-csharp, 0.0.3"                
#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 conductor-csharp as a Cake Addin
#addin nuget:?package=conductor-csharp&version=0.0.3

// Install conductor-csharp as a Cake Tool
#tool nuget:?package=conductor-csharp&version=0.0.3                

conductor-csharp

Netflix Conductor Client SDK

To find out more about Conductor visit: https://github.com/Netflix/conductor

conductor-csharp repository provides the client SDKs to build Task Workers and Clients in C#

Quick Start

  1. Get Secrets
  2. Write workers
  3. Run workers
  4. Worker Configurations
  5. Starting workflow

Get Secrets

Executing workflow or polling a task from a playground requires keyId and keySecret. Please follow guide to provision one for your application.

Write workers

 internal class MyWorkflowTask : IWorkflowTask
    {
        public MyWorkflowTask(){}

        public string TaskType => "test_ctask";
        public int? Priority => null;

        public async Task<TaskResult> Execute(Conductor.Client.Models.Task task, CancellationToken token)
        {
           Dictionary<string, object> newOutput = new Dictionary<string, object>();
           newOutput.Add("output", "1");
           return task.Completed(task.OutputData.MergeValues(newOutput));
        }
    }

 internal class MyWorkflowTask2 : IWorkflowTask
    {
        public MyWorkflowTask2(){}

        public string TaskType => "test_ctask2";
        public int? Priority => null;

        public async Task<TaskResult> Execute(Conductor.Client.Models.Task task, CancellationToken token)
        {
           Dictionary<string, object> newOutput = new Dictionary<string, object>();
           //Reuse the existing code written in C#
           newOutput.Add("output", "success");
           return task.Completed(task.OutputData.MergeValues(newOutput));
        }
    }

Run workers

Create main method that does the following:

  1. Adds configurations such as metrics, authentication, thread count, Conductor server URL
  2. Add your workers
  3. Start the workers to poll for work
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Collections.Generic;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Conductor.Client.Models;
using Conductor.Client.Extensions;
using Conductor.Client.Interfaces;

using Task = System.Threading.Tasks.Task;

namespace SimpleConductorWorker
{
    class Program
    {
        static async Task Main(string[] args)
        {
           await new HostBuilder()
                .ConfigureServices((ctx, services) =>
                {

                    Configuration configuration = new Configuration(new ConcurrentDictionary<string, string>(), "keyId", "keySecret");
                    services.AddConductorWorker(configuration);
                    services.AddConductorWorkflowTask<MyWorkflowTask>();
                    services.AddHostedService<WorkflowsWorkerService>();
                })
                .ConfigureLogging(logging =>
                {
                    logging.SetMinimumLevel(LogLevel.Debug);
                    logging.AddConsole();
                })
                .RunConsoleAsync();
        }
    }

    internal class WorkflowsWorkerService : BackgroundService
    {
        private readonly IWorkflowTaskCoordinator workflowTaskCoordinator;
        private readonly IEnumerable<IWorkflowTask> workflowTasks;

        public WorkflowsWorkerService(
            IWorkflowTaskCoordinator workflowTaskCoordinator,
            IEnumerable<IWorkflowTask> workflowTasks
        )
        {
            this.workflowTaskCoordinator = workflowTaskCoordinator;
            this.workflowTasks = workflowTasks;
        }

        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            foreach (var worker in workflowTasks)
            {
                workflowTaskCoordinator.RegisterWorker(worker);
            }
            # start all the workers so that it can poll for the tasks
            await workflowTaskCoordinator.Start();
        }
    }
}

Save above code with workers code in Program.cs and run it using consoleApplication. Alternatively it can also be hosted as windows service.

Worker Configurations

Worker configuration is handled via Configuraiton object passed when initializing TaskHandler

Starting workflow

Below is the code snippet in order to start the workflow,

//Optional headers clients wants to pass.
Dictionary<string, Object> optionalHeaders = new Dictionary<string, Object>();
Configuration configuration = new Configuration(optionalHeaders, "keyId", "keySecret", "https://play.orkes.io/");
WorkflowResourceApi workflowResourceApi = new WorkflowResourceApi(configuration);
Dictionary<string, Object> input = new Dictionary<string, Object>();
//Fill the input map which workflow consumes.
workflowResourceApi.StartWorkflow("Stack_overflow_sequential_manan", input, 1);

Please go through Conductor.Api package to find out supported apis

Running Conductor server locally in 2-minute

More details on how to run Conductor see https://netflix.github.io/conductor/server/

Use the script below to download and start the server locally. The server runs in memory and no data saved upon exit.

export CONDUCTOR_VER=3.5.2
export REPO_URL=https://repo1.maven.org/maven2/com/netflix/conductor/conductor-server
curl $REPO_URL/$CONDUCTOR_VER/conductor-server-$CONDUCTOR_VER-boot.jar \
--output conductor-server-$CONDUCTOR_VER-boot.jar; java -jar conductor-server-$CONDUCTOR_VER-boot.jar 

Execute workers

Run above program as console app or windows service

Create your first workflow

Now, let's create a new workflow and see your task worker code in execution!

Create a new Task Metadata for the worker you just created

curl -X 'POST' \
  'http://localhost:8080/api/metadata/taskdefs' \
  -H 'accept: */*' \
  -H 'Content-Type: application/json' \
  -d '[{
    "name": "test_ctask",
    "description": "C# task example",
    "retryCount": 3,
    "retryLogic": "FIXED",
    "retryDelaySeconds": 10,
    "timeoutSeconds": 300,
    "timeoutPolicy": "TIME_OUT_WF",
    "responseTimeoutSeconds": 180,
    "ownerEmail": "example@example.com"
}]'

Create a workflow that uses the task

curl -X 'POST' \
  'http://localhost:8080/api/metadata/workflow' \
  -H 'accept: */*' \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "workflow_with_csharp_task_example",
    "description": "Workflow with C# Task example",
    "version": 1,
    "tasks": [
      {
        "name": "test_ctask",
        "taskReferenceName": "test_ctask",
        "inputParameters": {},
        "type": "SIMPLE"
      }
    ],
    "inputParameters": [],
    "outputParameters": {
      "workerOutput": "${test_ctask.output}"
    },
    "schemaVersion": 2,
    "restartable": true,
    "ownerEmail": "example@example.com",
    "timeoutPolicy": "ALERT_ONLY",
    "timeoutSeconds": 0
}'

Start a new workflow execution

curl -X 'POST' \
  'http://localhost:8080/api/workflow/workflow_with_csharp_task_example?priority=0' \
  -H 'accept: text/plain' \
  -H 'Content-Type: application/json' \
  -d '{}'
Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in 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.0.15 12,312 6/6/2024
1.0.14 52,807 3/19/2024
1.0.13 4,716 1/4/2024
1.0.12 30,270 8/29/2023
1.0.11 18,929 5/11/2023
1.0.10 191 5/11/2023
1.0.9 196 5/9/2023
1.0.8 200 5/8/2023
1.0.7 1,051 3/23/2023
1.0.6 247 3/22/2023
1.0.5 242 3/22/2023
1.0.4 295 3/16/2023
1.0.3 273 3/15/2023
1.0.2 271 3/15/2023
1.0.1 254 3/12/2023
1.0.0 306 3/6/2023
0.1.10 127,314 2/12/2023
0.1.9 320 2/11/2023
0.1.8 1,018 1/25/2023
0.1.7 18,445 1/3/2023
0.1.6 18,743 12/19/2022
0.1.5 359 12/15/2022
0.1.3 358 12/15/2022
0.1.1 366 12/15/2022
0.1.0 403 12/3/2022
0.0.9 389 12/3/2022
0.0.8 388 12/3/2022
0.0.7 388 12/3/2022
0.0.6 2,540 9/15/2022
0.0.5 956 4/15/2022
0.0.4 464 4/14/2022
0.0.3 483 4/13/2022
0.0.2 464 4/7/2022
0.0.1 493 4/6/2022