Skip to content

Getting Started

Akash Kava edited this page Nov 10, 2021 · 10 revisions

Configure Workflow Service

public class WorkflowContext: EternityContext {

   public WorkflowContext(IServiceProvider services):
        base(new EternityAzureStorage(("ET", "azure storage connection string...")), 
            services, new EternityClock()) {
   }
}

// register this as background service
public class WorkflowBackgroundService : BackgroundService {
    private readonly WorkflowContext workflowContext;
    private readonly TelemetryClient telemetryClient;

    public WorkflowBackgroundService(WorkflowContext workflowContext, TelemetryClient telemetryClient)
    {
        this.workflowContext = workflowContext;
        this.telemetryClient = telemetryClient;
    }

    protected async override Task ExecuteAsync(CancellationToken stoppingToken) {
        while (!stoppingToken.IsCancellationRequested) {
            try {
                await workflowService.ProcessMessagesAsync(cancellationToken: stoppingToken);
            } catch (Exception ex) {
                telemetryClient.TrackException(ex);
            }
        }
    }
}

Register Service Scope

To enable Microsoft.DependencyInjection.Extensions Scope, add following in configure method.

services.AddEternityServiceScope();

This will make every activity execute in separate service scope, you can inject scoped services in Activities.

Create new workflow

Each workflow is identified by unique alpha numeric ID, it can be anything but it has to be unique. If you use Azure Storage as Eternity Storage then ID must be escaped. If you do not specify ID, a new Guid will be created. CreateAsync has an overload which allows you to specify ID and input. Input does not have to be unique, but ID has to be unique per workflow.

// create new workflow and execute now
var id = await SignupWorkflow.CreateAsync(context, "[email protected]");

// raise an event...
await context.RaiseEventAsync(id, SignupWorkflow.Verify, verificationCode);

Signup Example

Lets assume we want to verify email address of user before signup, we want to set max timeout to 45 minutes and maximum 3 retries.

Activities are methods of the same class marked with [Activity] attribute and methods must be public and virtual.

Activities can also be scheduled in future by passing a parameter marked with [Schedule] attribute as shown below.

public class SignupWorkflow : Workflow<SignupWorkflow, string, string> {

    // name of external event
    public const string Resend = nameof(Resend);

    // name of external event
    public const string Verify = nameof(Verify);

    public override async Task<string> RunAsync(string input)
    {
        var maxWait = TimeSpan.FromMinutes(15);
        var code = (this.CurrentUtc.Ticks & 0xF).ToString();
        await SendEmailAsync(input, code);
        for (int i = 0; i < 3; i++)
        {
            var (name, result) = await WaitForExternalEventsAsync(maxWait, Resend, Verify);
            switch(name)
            {
                case Verify:
                    if(result == code)
                    {
                        return "Verified";
                    }
                    break;
                case Resend:
                    await SendEmailAsync(input, code, i);
                    break;
            }
        }
        return "NotVerified";
    }

    [Activity]
    public virtual async Task<string> SendEmailAsync(
        string emailAddress, 
        string code, 
        int attempt = -1,
        [Inject] MockEmailService emailService = null) {
        await Task.Delay(100);
        emailService.Emails.Add((emailAddress, code, CurrentUtc));
        return $"{emailService.Emails.Count-1}";
    }
}
Clone this wiki locally