-
Notifications
You must be signed in to change notification settings - Fork 1
Getting Started
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);
}
}
}
}
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.
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);
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}";
}
}