From dce24b4f3bd6eeecaf7e5c4b79346e4a2f3ded63 Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Fri, 29 Nov 2019 13:32:05 +0100 Subject: [PATCH] Refactor rename to updated workflow terminology --- .../Controllers/HttpWorkflowsController.cs | 8 +- .../Handlers/SignalRequestHandler.cs | 12 +- .../Handlers/TriggerRequestHandler.cs | 10 +- .../Consumers/WorkflowConsumer.cs | 8 +- .../HostedServices/TimersHostedService.cs | 2 +- .../Activities/TriggerSignal.cs | 8 +- .../Activities/TriggerWorkflow.cs | 8 +- .../Extensions/WorkflowInvokerExtensions.cs | 4 +- .../Models/WorkflowStatus.cs | 9 +- .../Results/ActivityExecutionResult.cs | 6 +- .../Elsa.Abstractions/Results/NoopResult.cs | 2 +- .../Services/Extensions/WorkflowExtensions.cs | 6 +- .../Extensions/WorkflowInvokerExtensions.cs | 4 +- ...IWorkflowInvoker.cs => IWorkflowRunner.cs} | 124 +-- .../Models/IActivityExecutionResult.cs | 2 +- .../Models/WorkflowExecutionContext.cs | 6 +- .../ElsaServiceCollectionExtensions.cs | 2 +- .../Memory/MemoryWorkflowInstanceStore.cs | 2 +- src/core/Elsa.Core/Results/CombinedResult.cs | 4 +- .../Elsa.Core/Results/FaultWorkflowResult.cs | 2 +- .../Elsa.Core/Results/FinishWorkflowResult.cs | 2 +- src/core/Elsa.Core/Results/HaltResult.cs | 4 +- src/core/Elsa.Core/Results/OutcomeResult.cs | 2 +- src/core/Elsa.Core/Results/OutputResult.cs | 2 +- .../Results/ScheduleActivityResult.cs | 2 +- .../{WorkflowInvoker.cs => WorkflowRunner.cs} | 910 +++++++++--------- .../WorkflowDefinitionController.cs | 6 +- .../Views/WorkflowDefinition/Index.cshtml | 6 +- .../Extensions/WorkflowStatusExtensions.cs | 6 +- .../Services/CosmosDbWorkflowInstanceStore.cs | 2 +- ...ntityFrameworkCoreWorkflowInstanceStore.cs | 2 +- .../Services/MongoWorkflowInstanceStore.cs | 2 +- .../Services/YesSqlWorkflowInstanceStore.cs | 2 +- src/samples/Sample01/Program.cs | 4 +- src/samples/Sample02/Program.cs | 4 +- src/samples/Sample03/Program.cs | 4 +- src/samples/Sample04/Program.cs | 4 +- src/samples/Sample09/Program.cs | 4 +- src/samples/Sample10/Program.cs | 4 +- src/samples/Sample11/Program.cs | 4 +- src/samples/Sample12/Program.cs | 4 +- src/samples/Sample13/Program.cs | 4 +- src/samples/Sample14/Program.cs | 4 +- src/samples/Sample15/Program.cs | 4 +- src/samples/Sample17/Program.cs | 4 +- src/samples/Sample18/Program.cs | 4 +- src/samples/Sample20/Program.cs | 6 +- .../Mutations/RunWorkflow.cs | 8 +- 48 files changed, 622 insertions(+), 621 deletions(-) rename src/core/Elsa.Abstractions/Services/{IWorkflowInvoker.cs => IWorkflowRunner.cs} (89%) rename src/core/Elsa.Core/Services/{WorkflowInvoker.cs => WorkflowRunner.cs} (94%) diff --git a/src/activities/Elsa.Activities.Http/Controllers/HttpWorkflowsController.cs b/src/activities/Elsa.Activities.Http/Controllers/HttpWorkflowsController.cs index c5681d705..aa0ab362e 100644 --- a/src/activities/Elsa.Activities.Http/Controllers/HttpWorkflowsController.cs +++ b/src/activities/Elsa.Activities.Http/Controllers/HttpWorkflowsController.cs @@ -14,16 +14,16 @@ namespace Elsa.Activities.Http.Controllers public class HttpWorkflowsController : ControllerBase { private readonly ITokenService tokenService; - private readonly IWorkflowInvoker workflowInvoker; + private readonly IWorkflowRunner workflowRunner; private readonly IWorkflowInstanceStore workflowInstanceStore; public HttpWorkflowsController( ITokenService tokenService, - IWorkflowInvoker workflowInvoker, + IWorkflowRunner workflowRunner, IWorkflowInstanceStore workflowInstanceStore) { this.tokenService = tokenService; - this.workflowInvoker = workflowInvoker; + this.workflowRunner = workflowRunner; this.workflowInstanceStore = workflowInstanceStore; } @@ -42,7 +42,7 @@ namespace Elsa.Activities.Http.Controllers var input = new Variables(); input.SetVariable("Signal", signal.Name); - await workflowInvoker.ResumeAsync(workflowInstance, input, cancellationToken: cancellationToken); + await workflowRunner.ResumeAsync(workflowInstance, input, cancellationToken: cancellationToken); return HttpContext.Items.ContainsKey(WorkflowHttpResult.Instance) ? (IActionResult)new EmptyResult() diff --git a/src/activities/Elsa.Activities.Http/RequestHandlers/Handlers/SignalRequestHandler.cs b/src/activities/Elsa.Activities.Http/RequestHandlers/Handlers/SignalRequestHandler.cs index 266919d89..e813f824e 100644 --- a/src/activities/Elsa.Activities.Http/RequestHandlers/Handlers/SignalRequestHandler.cs +++ b/src/activities/Elsa.Activities.Http/RequestHandlers/Handlers/SignalRequestHandler.cs @@ -15,7 +15,7 @@ namespace Elsa.Activities.Http.RequestHandlers.Handlers { private readonly HttpContext httpContext; private readonly ITokenService tokenService; - private readonly IWorkflowInvoker workflowInvoker; + private readonly IWorkflowRunner workflowRunner; private readonly IWorkflowRegistry workflowRegistry; private readonly IWorkflowFactory workflowFactory; private readonly IWorkflowInstanceStore workflowInstanceStore; @@ -24,14 +24,14 @@ namespace Elsa.Activities.Http.RequestHandlers.Handlers public SignalRequestHandler( IHttpContextAccessor httpContextAccessor, ITokenService tokenService, - IWorkflowInvoker workflowInvoker, + IWorkflowRunner workflowRunner, IWorkflowRegistry workflowRegistry, IWorkflowFactory workflowFactory, IWorkflowInstanceStore workflowInstanceStore) { httpContext = httpContextAccessor.HttpContext; this.tokenService = tokenService; - this.workflowInvoker = workflowInvoker; + this.workflowRunner = workflowRunner; this.workflowRegistry = workflowRegistry; this.workflowFactory = workflowFactory; this.workflowInstanceStore = workflowInstanceStore; @@ -51,7 +51,7 @@ namespace Elsa.Activities.Http.RequestHandlers.Handlers return new NotFoundResult(); if (!CheckIfExecuting(workflowInstance)) - return new BadRequestResult($"Cannot signal a workflow with status other than {WorkflowStatus.Executing}. Actual workflow status: {workflowInstance.Status}."); + return new BadRequestResult($"Cannot signal a workflow with status other than {WorkflowStatus.Running}. Actual workflow status: {workflowInstance.Status}."); await ResumeWorkflowAsync(workflowInstance, signal); @@ -69,7 +69,7 @@ namespace Elsa.Activities.Http.RequestHandlers.Handlers await workflowInstanceStore.GetByIdAsync(signal.WorkflowInstanceId, cancellationToken); private bool CheckIfExecuting(WorkflowInstance workflowInstance) => - workflowInstance.Status == WorkflowStatus.Executing; + workflowInstance.Status == WorkflowStatus.Running; private async Task ResumeWorkflowAsync(WorkflowInstance workflowInstance, Signal signal) { @@ -83,7 +83,7 @@ namespace Elsa.Activities.Http.RequestHandlers.Handlers var workflow = workflowFactory.CreateWorkflow(workflowDefinition, input, workflowInstance); var blockingSignalActivities = workflow.BlockingActivities.ToList(); - await workflowInvoker.ResumeAsync(workflow, blockingSignalActivities, cancellationToken); + await workflowRunner.ResumeAsync(workflow, blockingSignalActivities, cancellationToken); } } } \ No newline at end of file diff --git a/src/activities/Elsa.Activities.Http/RequestHandlers/Handlers/TriggerRequestHandler.cs b/src/activities/Elsa.Activities.Http/RequestHandlers/Handlers/TriggerRequestHandler.cs index 95e200956..33507394c 100644 --- a/src/activities/Elsa.Activities.Http/RequestHandlers/Handlers/TriggerRequestHandler.cs +++ b/src/activities/Elsa.Activities.Http/RequestHandlers/Handlers/TriggerRequestHandler.cs @@ -18,19 +18,19 @@ namespace Elsa.Activities.Http.RequestHandlers.Handlers public class TriggerRequestHandler : IRequestHandler { private readonly HttpContext httpContext; - private readonly IWorkflowInvoker workflowInvoker; + private readonly IWorkflowRunner workflowRunner; private readonly IWorkflowRegistry registry; private readonly IWorkflowInstanceStore workflowInstanceStore; private readonly CancellationToken cancellationToken; public TriggerRequestHandler( IHttpContextAccessor httpContext, - IWorkflowInvoker workflowInvoker, + IWorkflowRunner workflowRunner, IWorkflowRegistry registry, IWorkflowInstanceStore workflowInstanceStore) { this.httpContext = httpContext.HttpContext; - this.workflowInvoker = workflowInvoker; + this.workflowRunner = workflowRunner; this.registry = registry; this.workflowInstanceStore = workflowInstanceStore; cancellationToken = httpContext.HttpContext.RequestAborted; @@ -87,7 +87,7 @@ namespace Elsa.Activities.Http.RequestHandlers.Handlers { foreach (var item in items) { - await workflowInvoker.StartAsync( + await workflowRunner.RunAsync( item.Item1, Variables.Empty, new[] { item.Item2.Id }, @@ -99,7 +99,7 @@ namespace Elsa.Activities.Http.RequestHandlers.Handlers { foreach (var (workflowInstance, activity) in items) { - await workflowInvoker.ResumeAsync( + await workflowRunner.ResumeAsync( workflowInstance, Variables.Empty, new[] { activity.Id }, diff --git a/src/activities/Elsa.Activities.MassTransit/Consumers/WorkflowConsumer.cs b/src/activities/Elsa.Activities.MassTransit/Consumers/WorkflowConsumer.cs index 023975d2f..ce8b24e84 100644 --- a/src/activities/Elsa.Activities.MassTransit/Consumers/WorkflowConsumer.cs +++ b/src/activities/Elsa.Activities.MassTransit/Consumers/WorkflowConsumer.cs @@ -19,11 +19,11 @@ namespace Elsa.Activities.MassTransit.Consumers new PropertyCorrelationIdSelector("CommandId") }; - private readonly IWorkflowInvoker workflowInvoker; + private readonly IWorkflowRunner workflowRunner; - public WorkflowConsumer(IWorkflowInvoker workflowInvoker) + public WorkflowConsumer(IWorkflowRunner workflowRunner) { - this.workflowInvoker = workflowInvoker; + this.workflowRunner = workflowRunner; } public async Task Consume(ConsumeContext context) @@ -42,7 +42,7 @@ namespace Elsa.Activities.MassTransit.Consumers break; } - await workflowInvoker.TriggerAsync( + await workflowRunner.TriggerAsync( activityType, input, correlationId.ToString(), diff --git a/src/activities/Elsa.Activities.Timers/HostedServices/TimersHostedService.cs b/src/activities/Elsa.Activities.Timers/HostedServices/TimersHostedService.cs index abe2324c5..af07f0cae 100644 --- a/src/activities/Elsa.Activities.Timers/HostedServices/TimersHostedService.cs +++ b/src/activities/Elsa.Activities.Timers/HostedServices/TimersHostedService.cs @@ -37,7 +37,7 @@ namespace Elsa.Activities.Timers.HostedServices { using (var scope = serviceProvider.CreateScope()) { - var workflowInvoker = scope.ServiceProvider.GetRequiredService(); + var workflowInvoker = scope.ServiceProvider.GetRequiredService(); await workflowInvoker.TriggerAsync(nameof(TimerEvent), Variables.Empty, stoppingToken); await workflowInvoker.TriggerAsync(nameof(CronEvent), Variables.Empty, stoppingToken); await workflowInvoker.TriggerAsync(nameof(InstantEvent), Variables.Empty, stoppingToken); diff --git a/src/activities/Elsa.Activities.Workflows/Activities/TriggerSignal.cs b/src/activities/Elsa.Activities.Workflows/Activities/TriggerSignal.cs index bf6c684fd..6428f8282 100644 --- a/src/activities/Elsa.Activities.Workflows/Activities/TriggerSignal.cs +++ b/src/activities/Elsa.Activities.Workflows/Activities/TriggerSignal.cs @@ -19,11 +19,11 @@ namespace Elsa.Activities.Workflows.Activities )] public class TriggerSignal : Activity { - private readonly IWorkflowInvoker workflowInvoker; + private readonly IWorkflowRunner workflowRunner; - public TriggerSignal(IWorkflowInvoker workflowInvoker) + public TriggerSignal(IWorkflowRunner workflowRunner) { - this.workflowInvoker = workflowInvoker; + this.workflowRunner = workflowRunner; } [ActivityProperty(Hint = "An expression that evaluates to the name of the signal to trigger.")] @@ -57,7 +57,7 @@ namespace Elsa.Activities.Workflows.Activities input.SetVariable("Signal", signal); - await workflowInvoker.TriggerAsync( + await workflowRunner.TriggerAsync( nameof(Signaled), input, correlationId, diff --git a/src/activities/Elsa.Activities.Workflows/Activities/TriggerWorkflow.cs b/src/activities/Elsa.Activities.Workflows/Activities/TriggerWorkflow.cs index a819b8b84..1f61c7837 100644 --- a/src/activities/Elsa.Activities.Workflows/Activities/TriggerWorkflow.cs +++ b/src/activities/Elsa.Activities.Workflows/Activities/TriggerWorkflow.cs @@ -17,11 +17,11 @@ namespace Elsa.Activities.Workflows.Activities )] public class TriggerWorkflow : Activity { - private readonly IWorkflowInvoker workflowInvoker; + private readonly IWorkflowRunner workflowRunner; - public TriggerWorkflow(IWorkflowInvoker workflowInvoker) + public TriggerWorkflow(IWorkflowRunner workflowRunner) { - this.workflowInvoker = workflowInvoker; + this.workflowRunner = workflowRunner; } [ActivityProperty(Hint = "An expression that evaluates to the activity type to use when triggering workflows.")] @@ -53,7 +53,7 @@ namespace Elsa.Activities.Workflows.Activities var input = await context.EvaluateAsync(Input, cancellationToken); var correlationId = await context.EvaluateAsync(CorrelationId, cancellationToken); - await workflowInvoker.TriggerAsync( + await workflowRunner.TriggerAsync( activityType, input, correlationId, diff --git a/src/activities/Elsa.Activities.Workflows/Extensions/WorkflowInvokerExtensions.cs b/src/activities/Elsa.Activities.Workflows/Extensions/WorkflowInvokerExtensions.cs index 599405991..a7ad50fc9 100644 --- a/src/activities/Elsa.Activities.Workflows/Extensions/WorkflowInvokerExtensions.cs +++ b/src/activities/Elsa.Activities.Workflows/Extensions/WorkflowInvokerExtensions.cs @@ -11,7 +11,7 @@ namespace Elsa.Activities.Workflows.Extensions public static class WorkflowInvokerExtensions { public static async Task TriggerSignalAsync( - this IWorkflowInvoker workflowInvoker, + this IWorkflowRunner workflowRunner, string signalName, Variables input = default, Func activityStatePredicate = null, @@ -24,7 +24,7 @@ namespace Elsa.Activities.Workflows.Extensions if (input != null) combinedInput.SetVariables(input); - await workflowInvoker.TriggerAsync(nameof(Signaled), combinedInput, correlationId, activityStatePredicate, cancellationToken); + await workflowRunner.TriggerAsync(nameof(Signaled), combinedInput, correlationId, activityStatePredicate, cancellationToken); } } } \ No newline at end of file diff --git a/src/core/Elsa.Abstractions/Models/WorkflowStatus.cs b/src/core/Elsa.Abstractions/Models/WorkflowStatus.cs index 2df3ff352..d4fe30fc9 100644 --- a/src/core/Elsa.Abstractions/Models/WorkflowStatus.cs +++ b/src/core/Elsa.Abstractions/Models/WorkflowStatus.cs @@ -2,10 +2,11 @@ { public enum WorkflowStatus { - Idle, - Executing, - Finished, + Pending, + Running, + Completed, + Suspended, Faulted, - Aborted + Cancelled } } diff --git a/src/core/Elsa.Abstractions/Results/ActivityExecutionResult.cs b/src/core/Elsa.Abstractions/Results/ActivityExecutionResult.cs index 46a068c7c..64e23be16 100644 --- a/src/core/Elsa.Abstractions/Results/ActivityExecutionResult.cs +++ b/src/core/Elsa.Abstractions/Results/ActivityExecutionResult.cs @@ -7,13 +7,13 @@ namespace Elsa.Results { public abstract class ActivityExecutionResult : IActivityExecutionResult { - public virtual Task ExecuteAsync(IWorkflowInvoker invoker, WorkflowExecutionContext workflowContext, CancellationToken cancellationToken) + public virtual Task ExecuteAsync(IWorkflowRunner runner, WorkflowExecutionContext workflowContext, CancellationToken cancellationToken) { - Execute(invoker, workflowContext); + Execute(runner, workflowContext); return Task.CompletedTask; } - protected virtual void Execute(IWorkflowInvoker invoker, WorkflowExecutionContext workflowContext) + protected virtual void Execute(IWorkflowRunner runner, WorkflowExecutionContext workflowContext) { } } diff --git a/src/core/Elsa.Abstractions/Results/NoopResult.cs b/src/core/Elsa.Abstractions/Results/NoopResult.cs index 78428936e..225372d72 100644 --- a/src/core/Elsa.Abstractions/Results/NoopResult.cs +++ b/src/core/Elsa.Abstractions/Results/NoopResult.cs @@ -8,7 +8,7 @@ namespace Elsa.Results /// public class NoopResult : ActivityExecutionResult { - protected override void Execute(IWorkflowInvoker invoker, WorkflowExecutionContext workflowContext) + protected override void Execute(IWorkflowRunner runner, WorkflowExecutionContext workflowContext) { // Noop. } diff --git a/src/core/Elsa.Abstractions/Services/Extensions/WorkflowExtensions.cs b/src/core/Elsa.Abstractions/Services/Extensions/WorkflowExtensions.cs index 1db659d43..1e9a26120 100644 --- a/src/core/Elsa.Abstractions/Services/Extensions/WorkflowExtensions.cs +++ b/src/core/Elsa.Abstractions/Services/Extensions/WorkflowExtensions.cs @@ -8,13 +8,13 @@ namespace Elsa.Services.Extensions { public static class WorkflowExtensions { - public static bool IsExecuting(this Workflow workflow) => workflow.Status == WorkflowStatus.Executing; + public static bool IsExecuting(this Workflow workflow) => workflow.Status == WorkflowStatus.Running; public static bool IsFaultedOrAborted(this Workflow workflow) => - workflow.Status == WorkflowStatus.Aborted || + workflow.Status == WorkflowStatus.Cancelled || workflow.Status == WorkflowStatus.Faulted; - public static bool IsFinished(this Workflow workflow) => workflow.Status == WorkflowStatus.Finished; + public static bool IsFinished(this Workflow workflow) => workflow.Status == WorkflowStatus.Completed; public static IEnumerable GetStartActivities(this Workflow workflow) { diff --git a/src/core/Elsa.Abstractions/Services/Extensions/WorkflowInvokerExtensions.cs b/src/core/Elsa.Abstractions/Services/Extensions/WorkflowInvokerExtensions.cs index ba2b757a3..9435989ac 100644 --- a/src/core/Elsa.Abstractions/Services/Extensions/WorkflowInvokerExtensions.cs +++ b/src/core/Elsa.Abstractions/Services/Extensions/WorkflowInvokerExtensions.cs @@ -10,12 +10,12 @@ namespace Elsa.Services.Extensions /// Starts new workflows that start with the specified activity name and resumes halted workflows that are blocked on activities with the specified activity name. /// public static Task TriggerAsync( - this IWorkflowInvoker workflowInvoker, + this IWorkflowRunner workflowRunner, string activityType, Variables input, CancellationToken cancellationToken = default) { - return workflowInvoker.TriggerAsync(activityType, input, cancellationToken: cancellationToken); + return workflowRunner.TriggerAsync(activityType, input, cancellationToken: cancellationToken); } } } \ No newline at end of file diff --git a/src/core/Elsa.Abstractions/Services/IWorkflowInvoker.cs b/src/core/Elsa.Abstractions/Services/IWorkflowRunner.cs similarity index 89% rename from src/core/Elsa.Abstractions/Services/IWorkflowInvoker.cs rename to src/core/Elsa.Abstractions/Services/IWorkflowRunner.cs index ccb73d8fc..8062a2daa 100644 --- a/src/core/Elsa.Abstractions/Services/IWorkflowInvoker.cs +++ b/src/core/Elsa.Abstractions/Services/IWorkflowRunner.cs @@ -1,63 +1,63 @@ -using System; -using System.Collections.Generic; -using System.Threading; -using System.Threading.Tasks; -using Elsa.Models; -using Elsa.Services.Models; -using Newtonsoft.Json.Linq; - -namespace Elsa.Services -{ - public interface IWorkflowInvoker - { - Task StartAsync( - Workflow workflow, - IEnumerable startActivities = default, - CancellationToken cancellationToken = default - ); - - Task StartAsync( - Variables input = default, - IEnumerable startActivityIds = default, - string correlationId = default, - CancellationToken cancellationToken = default) where T : IWorkflow, new(); - - Task StartAsync( - WorkflowDefinitionVersion workflowDefinition, - Variables input = default, - IEnumerable startActivityIds = default, - string correlationId = default, - CancellationToken cancellationToken = default - ); - - Task ResumeAsync( - Workflow workflow, - IEnumerable startActivities = default, - CancellationToken cancellationToken = default - ); - - Task ResumeAsync( - WorkflowInstance workflowInstance, - Variables input = default, - IEnumerable startActivityIds = default, - CancellationToken cancellationToken = default - ) where T : IWorkflow, new(); - - Task ResumeAsync( - WorkflowInstance workflowInstance, - Variables input = default, - IEnumerable startActivityIds = default, - CancellationToken cancellationToken = default - ); - - /// - /// Starts new workflows that start with the specified activity name and resumes halted workflows that are blocked on activities with the specified activity name. - /// - Task> TriggerAsync( - string activityType, - Variables input = default, - string correlationId = default, - Func activityStatePredicate = default, - CancellationToken cancellationToken = default); - } +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using Elsa.Models; +using Elsa.Services.Models; +using Newtonsoft.Json.Linq; + +namespace Elsa.Services +{ + public interface IWorkflowRunner + { + Task RunAsync( + Workflow workflow, + IEnumerable startActivities = default, + CancellationToken cancellationToken = default + ); + + Task RunAsync( + Variables input = default, + IEnumerable startActivityIds = default, + string correlationId = default, + CancellationToken cancellationToken = default) where T : IWorkflow, new(); + + Task RunAsync( + WorkflowDefinitionVersion workflowDefinition, + Variables input = default, + IEnumerable startActivityIds = default, + string correlationId = default, + CancellationToken cancellationToken = default + ); + + Task ResumeAsync( + Workflow workflow, + IEnumerable startActivities = default, + CancellationToken cancellationToken = default + ); + + Task ResumeAsync( + WorkflowInstance workflowInstance, + Variables input = default, + IEnumerable startActivityIds = default, + CancellationToken cancellationToken = default + ) where T : IWorkflow, new(); + + Task ResumeAsync( + WorkflowInstance workflowInstance, + Variables input = default, + IEnumerable startActivityIds = default, + CancellationToken cancellationToken = default + ); + + /// + /// Starts new workflows that start with the specified activity name and resumes halted workflows that are blocked on activities with the specified activity name. + /// + Task> TriggerAsync( + string activityType, + Variables input = default, + string correlationId = default, + Func activityStatePredicate = default, + CancellationToken cancellationToken = default); + } } \ No newline at end of file diff --git a/src/core/Elsa.Abstractions/Services/Models/IActivityExecutionResult.cs b/src/core/Elsa.Abstractions/Services/Models/IActivityExecutionResult.cs index 1d5a1d2bd..a41282c07 100644 --- a/src/core/Elsa.Abstractions/Services/Models/IActivityExecutionResult.cs +++ b/src/core/Elsa.Abstractions/Services/Models/IActivityExecutionResult.cs @@ -5,6 +5,6 @@ namespace Elsa.Services.Models { public interface IActivityExecutionResult { - Task ExecuteAsync(IWorkflowInvoker invoker, WorkflowExecutionContext workflowContext, CancellationToken cancellationToken); + Task ExecuteAsync(IWorkflowRunner runner, WorkflowExecutionContext workflowContext, CancellationToken cancellationToken); } } diff --git a/src/core/Elsa.Abstractions/Services/Models/WorkflowExecutionContext.cs b/src/core/Elsa.Abstractions/Services/Models/WorkflowExecutionContext.cs index fe233e717..00ffb3c94 100644 --- a/src/core/Elsa.Abstractions/Services/Models/WorkflowExecutionContext.cs +++ b/src/core/Elsa.Abstractions/Services/Models/WorkflowExecutionContext.cs @@ -84,7 +84,7 @@ namespace Elsa.Services.Models public void Start() { Workflow.StartedAt = clock.GetCurrentInstant(); - Workflow.Status = WorkflowStatus.Executing; + Workflow.Status = WorkflowStatus.Running; } public void Fault(IActivity activity, Exception exception) => Fault(activity, exception.Message); @@ -109,14 +109,14 @@ namespace Elsa.Services.Models public void Finish() { Workflow.FinishedAt = clock.GetCurrentInstant(); - Workflow.Status = WorkflowStatus.Finished; + Workflow.Status = WorkflowStatus.Completed; Workflow.BlockingActivities.Clear(); } public void Abort() { Workflow.AbortedAt = clock.GetCurrentInstant(); - Workflow.Status = WorkflowStatus.Aborted; + Workflow.Status = WorkflowStatus.Cancelled; } public Variables GetVariables() => Workflow.Scopes diff --git a/src/core/Elsa.Core/Extensions/ElsaServiceCollectionExtensions.cs b/src/core/Elsa.Core/Extensions/ElsaServiceCollectionExtensions.cs index 6f1a8206b..8648d8f9b 100644 --- a/src/core/Elsa.Core/Extensions/ElsaServiceCollectionExtensions.cs +++ b/src/core/Elsa.Core/Extensions/ElsaServiceCollectionExtensions.cs @@ -80,7 +80,7 @@ namespace Microsoft.Extensions.DependencyInjection .AddSingleton() .AddTransient() .AddScoped() - .AddScoped() + .AddScoped() .AddScoped() .AddScoped() .AddTransient() diff --git a/src/core/Elsa.Core/Persistence/Memory/MemoryWorkflowInstanceStore.cs b/src/core/Elsa.Core/Persistence/Memory/MemoryWorkflowInstanceStore.cs index 54ded7257..960e738f6 100644 --- a/src/core/Elsa.Core/Persistence/Memory/MemoryWorkflowInstanceStore.cs +++ b/src/core/Elsa.Core/Persistence/Memory/MemoryWorkflowInstanceStore.cs @@ -51,7 +51,7 @@ namespace Elsa.Persistence.Memory { var query = workflowInstances.Values.AsQueryable(); - query = query.Where(x => x.Status == WorkflowStatus.Executing); + query = query.Where(x => x.Status == WorkflowStatus.Running); if (!string.IsNullOrWhiteSpace(correlationId)) query = query.Where(x => x.CorrelationId == correlationId); diff --git a/src/core/Elsa.Core/Results/CombinedResult.cs b/src/core/Elsa.Core/Results/CombinedResult.cs index 2ba732239..893e9a20e 100644 --- a/src/core/Elsa.Core/Results/CombinedResult.cs +++ b/src/core/Elsa.Core/Results/CombinedResult.cs @@ -21,11 +21,11 @@ namespace Elsa.Results public IReadOnlyCollection Results { get; } - public override async Task ExecuteAsync(IWorkflowInvoker invoker, WorkflowExecutionContext workflowContext, CancellationToken cancellationToken) + public override async Task ExecuteAsync(IWorkflowRunner runner, WorkflowExecutionContext workflowContext, CancellationToken cancellationToken) { foreach (var result in Results) { - await result.ExecuteAsync(invoker, workflowContext, cancellationToken); + await result.ExecuteAsync(runner, workflowContext, cancellationToken); } } } diff --git a/src/core/Elsa.Core/Results/FaultWorkflowResult.cs b/src/core/Elsa.Core/Results/FaultWorkflowResult.cs index 1858a925d..2f4811e2c 100644 --- a/src/core/Elsa.Core/Results/FaultWorkflowResult.cs +++ b/src/core/Elsa.Core/Results/FaultWorkflowResult.cs @@ -23,7 +23,7 @@ namespace Elsa.Results } public override async Task ExecuteAsync( - IWorkflowInvoker invoker, + IWorkflowRunner runner, WorkflowExecutionContext workflowContext, CancellationToken cancellationToken) { diff --git a/src/core/Elsa.Core/Results/FinishWorkflowResult.cs b/src/core/Elsa.Core/Results/FinishWorkflowResult.cs index 54ee787b1..f9e55a5d4 100644 --- a/src/core/Elsa.Core/Results/FinishWorkflowResult.cs +++ b/src/core/Elsa.Core/Results/FinishWorkflowResult.cs @@ -11,7 +11,7 @@ namespace Elsa.Results public class FinishWorkflowResult : ActivityExecutionResult { public override async Task ExecuteAsync( - IWorkflowInvoker invoker, + IWorkflowRunner runner, WorkflowExecutionContext workflowContext, CancellationToken cancellationToken) { diff --git a/src/core/Elsa.Core/Results/HaltResult.cs b/src/core/Elsa.Core/Results/HaltResult.cs index db8512cd1..34d7a415d 100644 --- a/src/core/Elsa.Core/Results/HaltResult.cs +++ b/src/core/Elsa.Core/Results/HaltResult.cs @@ -18,7 +18,7 @@ namespace Elsa.Results public bool ContinueOnFirstPass { get; } - public override async Task ExecuteAsync(IWorkflowInvoker invoker, WorkflowExecutionContext workflowContext, CancellationToken cancellationToken) + public override async Task ExecuteAsync(IWorkflowRunner runner, WorkflowExecutionContext workflowContext, CancellationToken cancellationToken) { var activity = workflowContext.CurrentActivity; @@ -29,7 +29,7 @@ namespace Elsa.Results workflowContext.IsFirstPass = false; - await result.ExecuteAsync(invoker, workflowContext, cancellationToken); + await result.ExecuteAsync(runner, workflowContext, cancellationToken); } else { diff --git a/src/core/Elsa.Core/Results/OutcomeResult.cs b/src/core/Elsa.Core/Results/OutcomeResult.cs index b3d2eb902..d9b4039c2 100644 --- a/src/core/Elsa.Core/Results/OutcomeResult.cs +++ b/src/core/Elsa.Core/Results/OutcomeResult.cs @@ -23,7 +23,7 @@ namespace Elsa.Results public IReadOnlyList EndpointNames { get; } - public override async Task ExecuteAsync(IWorkflowInvoker invoker, WorkflowExecutionContext workflowContext, CancellationToken cancellationToken) + public override async Task ExecuteAsync(IWorkflowRunner runner, WorkflowExecutionContext workflowContext, CancellationToken cancellationToken) { var currentActivity = workflowContext.CurrentActivity; diff --git a/src/core/Elsa.Core/Results/OutputResult.cs b/src/core/Elsa.Core/Results/OutputResult.cs index 115584a42..f882df0cd 100644 --- a/src/core/Elsa.Core/Results/OutputResult.cs +++ b/src/core/Elsa.Core/Results/OutputResult.cs @@ -13,7 +13,7 @@ namespace Elsa.Results public Variable Value { get; } - protected override void Execute(IWorkflowInvoker invoker, WorkflowExecutionContext workflowContext) + protected override void Execute(IWorkflowRunner runner, WorkflowExecutionContext workflowContext) { workflowContext.CurrentActivity.Output = Value; } diff --git a/src/core/Elsa.Core/Results/ScheduleActivityResult.cs b/src/core/Elsa.Core/Results/ScheduleActivityResult.cs index 9193692fb..dce2c6dbf 100644 --- a/src/core/Elsa.Core/Results/ScheduleActivityResult.cs +++ b/src/core/Elsa.Core/Results/ScheduleActivityResult.cs @@ -12,7 +12,7 @@ namespace Elsa.Results this.activity = activity; } - protected override void Execute(IWorkflowInvoker invoker, WorkflowExecutionContext workflowContext) + protected override void Execute(IWorkflowRunner runner, WorkflowExecutionContext workflowContext) { workflowContext.ScheduleActivity(activity); } diff --git a/src/core/Elsa.Core/Services/WorkflowInvoker.cs b/src/core/Elsa.Core/Services/WorkflowRunner.cs similarity index 94% rename from src/core/Elsa.Core/Services/WorkflowInvoker.cs rename to src/core/Elsa.Core/Services/WorkflowRunner.cs index 877d5b559..e3990ac35 100644 --- a/src/core/Elsa.Core/Services/WorkflowInvoker.cs +++ b/src/core/Elsa.Core/Services/WorkflowRunner.cs @@ -1,456 +1,456 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using Elsa.Extensions; -using Elsa.Models; -using Elsa.Persistence; -using Elsa.Services.Extensions; -using Elsa.Services.Models; -using Microsoft.Extensions.Logging; -using Newtonsoft.Json.Linq; -using NodaTime; - -namespace Elsa.Services -{ - internal class WorkflowInvoker : IWorkflowInvoker - { - private readonly IActivityInvoker activityInvoker; - private readonly IWorkflowFactory workflowFactory; - private readonly IWorkflowRegistry workflowRegistry; - private readonly IWorkflowInstanceStore workflowInstanceStore; - private readonly IEnumerable workflowEventHandlers; - private readonly IClock clock; - private readonly IServiceProvider serviceProvider; - private readonly ILogger logger; - - public WorkflowInvoker( - IActivityInvoker activityInvoker, - IWorkflowFactory workflowFactory, - IWorkflowRegistry workflowRegistry, - IWorkflowInstanceStore workflowInstanceStore, - IEnumerable workflowEventHandlers, - IClock clock, - IServiceProvider serviceProvider, - ILogger logger) - { - this.activityInvoker = activityInvoker; - this.workflowFactory = workflowFactory; - this.workflowRegistry = workflowRegistry; - this.workflowInstanceStore = workflowInstanceStore; - this.workflowEventHandlers = workflowEventHandlers; - this.clock = clock; - this.serviceProvider = serviceProvider; - this.logger = logger; - } - - public Task StartAsync( - Workflow workflow, - IEnumerable startActivities = default, - CancellationToken cancellationToken = default) - { - return ExecuteAsync(workflow, false, startActivities, cancellationToken); - } - - public Task StartAsync( - WorkflowDefinitionVersion workflowDefinition, - Variables input = default, - IEnumerable startActivityIds = default, - string correlationId = default, - CancellationToken cancellationToken = default) - { - var workflow = workflowFactory.CreateWorkflow(workflowDefinition, input, correlationId: correlationId); - var startActivities = workflow.Activities.Find(startActivityIds); - - return ExecuteAsync(workflow, false, startActivities, cancellationToken); - } - - public Task StartAsync( - Variables input = default, - IEnumerable startActivityIds = default, - string correlationId = default, - CancellationToken cancellationToken = default) where T : IWorkflow, new() - { - var workflow = workflowFactory.CreateWorkflow(input, correlationId: correlationId); - var startActivities = workflow.Activities.Find(startActivityIds); - - return ExecuteAsync(workflow, false, startActivities, cancellationToken); - } - - public Task ResumeAsync( - Workflow workflow, - IEnumerable startActivities = default, - CancellationToken cancellationToken = default) - { - return ExecuteAsync(workflow, true, startActivities, cancellationToken); - } - - public Task ResumeAsync( - WorkflowInstance workflowInstance, - Variables input = null, - IEnumerable startActivityIds = default, - CancellationToken cancellationToken = default) where T : IWorkflow, new() - { - var workflow = workflowFactory.CreateWorkflow(input, workflowInstance); - var startActivities = workflow.Activities.Find(startActivityIds); - return ExecuteAsync(workflow, true, startActivities, cancellationToken); - } - - public async Task ResumeAsync( - WorkflowInstance workflowInstance, - Variables input = null, - IEnumerable startActivityIds = default, - CancellationToken cancellationToken = default) - { - var definition = await workflowRegistry.GetWorkflowDefinitionAsync( - workflowInstance.DefinitionId, - VersionOptions.SpecificVersion(workflowInstance.Version), - cancellationToken); - var workflow = workflowFactory.CreateWorkflow(definition, input, workflowInstance); - return await ExecuteAsync(workflow, true, startActivityIds, cancellationToken); - } - - public async Task> TriggerAsync( - string activityType, - Variables input = default, - string correlationId = default, - Func activityStatePredicate = default, - CancellationToken cancellationToken = default) - { - var startedExecutionContexts = await StartManyAsync( - activityType, - input, - correlationId, - activityStatePredicate, - cancellationToken - ); - - var resumedExecutionContexts = await ResumeManyAsync( - activityType, - input, - correlationId, - activityStatePredicate, - cancellationToken - ); - - return startedExecutionContexts.Concat(resumedExecutionContexts); - } - - private async Task> ResumeManyAsync( - string activityType, - Variables input = default, - string correlationId = default, - Func activityStatePredicate = default, - CancellationToken cancellationToken = default) - { - var workflowInstances = await workflowInstanceStore - .ListByBlockingActivityAsync(activityType, correlationId, cancellationToken) - .ToListAsync(); - - if (activityStatePredicate != null) - workflowInstances = workflowInstances.Where(x => activityStatePredicate(x.Item2.State)).ToList(); - - return await ResumeManyAsync( - workflowInstances, - input, - cancellationToken - ); - } - - private async Task> StartManyAsync( - string activityType, - Variables input = default, - string correlationId = default, - Func activityStatePredicate = default, - CancellationToken cancellationToken = default) - { - var workflowDefinitions = await workflowRegistry.ListByStartActivityAsync(activityType, cancellationToken); - - if (activityStatePredicate != null) - workflowDefinitions = workflowDefinitions.Where(x => activityStatePredicate(x.Item2.State)); - - workflowDefinitions = await FilterRunningSingletonsAsync( - workflowDefinitions, - cancellationToken - ); - - return await StartManyAsync(workflowDefinitions, input, correlationId, cancellationToken); - } - - private Task ExecuteAsync( - Workflow workflow, - bool resume, - IEnumerable startActivityIds = default, - CancellationToken cancellationToken = default) - { - var startActivities = startActivityIds != null - ? workflow.Activities.Find(startActivityIds) - : Enumerable.Empty(); - - return ExecuteAsync(workflow, resume, startActivities, cancellationToken); - } - - private async Task ExecuteAsync( - Workflow workflow, - bool resume, - IEnumerable startActivities = default, - CancellationToken cancellationToken = default) - { - var workflowExecutionContext = await CreateWorkflowExecutionContextAsync( - workflow, - startActivities, - cancellationToken - ); - - var start = !resume; - - while (workflowExecutionContext.HasScheduledActivities) - { - var currentActivity = workflowExecutionContext.PopScheduledActivity(); - - var result = start - ? await ExecuteActivityAsync(workflowExecutionContext, currentActivity, cancellationToken) - : await ResumeActivityAsync(workflowExecutionContext, currentActivity, cancellationToken); - - if (result == null) - break; - - await result.ExecuteAsync(this, workflowExecutionContext, cancellationToken); - - workflowExecutionContext.IsFirstPass = false; - start = true; - } - - await FinalizeWorkflowExecutionAsync(workflowExecutionContext, cancellationToken); - - return workflowExecutionContext; - } - - private async Task> StartManyAsync( - IEnumerable<(WorkflowDefinitionVersion, ActivityDefinition)> workflowDefinitions, - Variables input, - string correlationId, - CancellationToken cancellationToken1) - { - var executionContexts = new List(); - - foreach (var (workflowDefinition, activityDefinition) in workflowDefinitions) - { - var startActivityIds = workflowDefinition.Activities - .Where(x => x.Id == activityDefinition.Id) - .Select(x => x.Id); - - var workflow = workflowFactory.CreateWorkflow(workflowDefinition, input, correlationId: correlationId); - - var executionContext = await ExecuteAsync( - workflow, - false, - startActivityIds, - cancellationToken1 - ); - executionContexts.Add(executionContext); - } - - return executionContexts; - } - - private async Task> ResumeManyAsync( - IEnumerable<(WorkflowInstance, ActivityInstance)> workflowInstances, - Variables input, - CancellationToken cancellationToken) - { - var executionContexts = new List(); - var workflowInstanceGroups = workflowInstances.GroupBy(x => x.Item1); - - foreach (var workflowInstanceGroup in workflowInstanceGroups) - { - var workflowInstance = workflowInstanceGroup.Key; - - var workflowDefinition = await workflowRegistry.GetWorkflowDefinitionAsync( - workflowInstance.DefinitionId, - VersionOptions.SpecificVersion(workflowInstance.Version), - cancellationToken - ); - - var workflow = workflowFactory.CreateWorkflow(workflowDefinition, input, workflowInstance); - - foreach (var activity in workflowInstanceGroup) - { - var executionContext = await ExecuteAsync( - workflow, - true, - new[] { activity.Item2.Id }, - cancellationToken - ); - - executionContexts.Add(executionContext); - } - } - - return executionContexts; - } - - private async Task FinalizeWorkflowExecutionAsync( - WorkflowExecutionContext workflowExecutionContext, - CancellationToken cancellationToken) - { - if (!workflowExecutionContext.Workflow.BlockingActivities.Any() && - workflowExecutionContext.Workflow.IsExecuting()) - { - workflowExecutionContext.Finish(); - } - else - { - // Notify event handlers that halting activities are about to be executed. - await workflowEventHandlers.InvokeAsync( - async x => await x.InvokingHaltedActivitiesAsync(workflowExecutionContext, cancellationToken), - logger - ); - - // Invoke Halted event on activity drivers that halted the workflow. - while (workflowExecutionContext.HasScheduledHaltingActivities) - { - var currentActivity = workflowExecutionContext.PopScheduledHaltingActivity(); - var result = await ExecuteActivityHaltedAsync( - workflowExecutionContext, - currentActivity, - cancellationToken - ); - - await result.ExecuteAsync(this, workflowExecutionContext, cancellationToken); - } - } - - // Notify event handlers that workflow execution has ended. - await workflowEventHandlers.InvokeAsync( - async x => await x.WorkflowInvokedAsync(workflowExecutionContext, cancellationToken), - logger - ); - } - - private async Task ExecuteActivityAsync( - WorkflowExecutionContext workflowContext, - IActivity activity, - CancellationToken cancellationToken) - { - return await InvokeActivityAsync( - workflowContext, - activity, - async () => await activityInvoker.ExecuteAsync(workflowContext, activity, cancellationToken), - cancellationToken - ); - } - - private async Task ResumeActivityAsync( - WorkflowExecutionContext workflowContext, - IActivity activity, - CancellationToken cancellationToken) - { - return await InvokeActivityAsync( - workflowContext, - activity, - async () => await activityInvoker.ResumeAsync(workflowContext, activity, cancellationToken), - cancellationToken - ); - } - - private async Task InvokeActivityAsync( - WorkflowExecutionContext workflowContext, - IActivity activity, - Func> executeAction, - CancellationToken cancellationToken) - { - try - { - if (cancellationToken.IsCancellationRequested) - { - workflowContext.Workflow.Status = WorkflowStatus.Aborted; - workflowContext.Workflow.FinishedAt = clock.GetCurrentInstant(); - return null; - } - - return await executeAction(); - } - catch (Exception ex) - { - FaultWorkflow(workflowContext, activity, ex); - } - - return null; - } - - private async Task ExecuteActivityHaltedAsync( - WorkflowExecutionContext workflowContext, - IActivity activity, - CancellationToken cancellationToken) - { - return await InvokeActivityAsync( - workflowContext, - activity, - async () => await activityInvoker.HaltedAsync(workflowContext, activity, cancellationToken), - cancellationToken - ); - } - - private void FaultWorkflow(WorkflowExecutionContext workflowContext, IActivity activity, Exception ex) - { - logger.LogError( - ex, - "An unhandled error occurred while executing an activity. Putting the workflow in the faulted state." - ); - workflowContext.Fault(activity, ex); - } - - private async Task CreateWorkflowExecutionContextAsync( - Workflow workflow, - IEnumerable startActivities, - CancellationToken cancellationToken) - { - var workflowExecutionContext = new WorkflowExecutionContext(workflow, clock, serviceProvider); - var startActivityList = startActivities?.ToList() ?? workflow.GetStartActivities().Take(1).ToList(); - - foreach (var startActivity in startActivityList) - { - if (await startActivity.CanExecuteAsync(workflowExecutionContext, cancellationToken)) - workflowExecutionContext.ScheduleActivity(startActivity); - } - - if (workflowExecutionContext.HasScheduledActivities) - { - workflow.BlockingActivities.RemoveWhere(startActivityList.Contains); - - if (workflowExecutionContext.Workflow.Status == WorkflowStatus.Idle) - workflowExecutionContext.Start(); - } - - return workflowExecutionContext; - } - - private async Task> FilterRunningSingletonsAsync( - IEnumerable<(WorkflowDefinitionVersion, ActivityDefinition)> workflowDefinitions, - CancellationToken cancellationToken) - { - var definitions = workflowDefinitions.ToList(); - var transients = definitions.Where(x => !x.Item1.IsSingleton).ToList(); - var singletons = definitions.Where(x => x.Item1.IsSingleton).ToList(); - var result = transients.ToList(); - - foreach (var definition in singletons) - { - var instances = await workflowInstanceStore.ListByStatusAsync( - definition.Item1.DefinitionId, - WorkflowStatus.Executing, - cancellationToken - ); - - if (!instances.Any()) - { - result.Add(definition); - } - } - - return result; - } - } +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Elsa.Extensions; +using Elsa.Models; +using Elsa.Persistence; +using Elsa.Services.Extensions; +using Elsa.Services.Models; +using Microsoft.Extensions.Logging; +using Newtonsoft.Json.Linq; +using NodaTime; + +namespace Elsa.Services +{ + internal class WorkflowRunner : IWorkflowRunner + { + private readonly IActivityInvoker activityInvoker; + private readonly IWorkflowFactory workflowFactory; + private readonly IWorkflowRegistry workflowRegistry; + private readonly IWorkflowInstanceStore workflowInstanceStore; + private readonly IEnumerable workflowEventHandlers; + private readonly IClock clock; + private readonly IServiceProvider serviceProvider; + private readonly ILogger logger; + + public WorkflowRunner( + IActivityInvoker activityInvoker, + IWorkflowFactory workflowFactory, + IWorkflowRegistry workflowRegistry, + IWorkflowInstanceStore workflowInstanceStore, + IEnumerable workflowEventHandlers, + IClock clock, + IServiceProvider serviceProvider, + ILogger logger) + { + this.activityInvoker = activityInvoker; + this.workflowFactory = workflowFactory; + this.workflowRegistry = workflowRegistry; + this.workflowInstanceStore = workflowInstanceStore; + this.workflowEventHandlers = workflowEventHandlers; + this.clock = clock; + this.serviceProvider = serviceProvider; + this.logger = logger; + } + + public Task RunAsync( + Workflow workflow, + IEnumerable startActivities = default, + CancellationToken cancellationToken = default) + { + return ExecuteAsync(workflow, false, startActivities, cancellationToken); + } + + public Task RunAsync( + WorkflowDefinitionVersion workflowDefinition, + Variables input = default, + IEnumerable startActivityIds = default, + string correlationId = default, + CancellationToken cancellationToken = default) + { + var workflow = workflowFactory.CreateWorkflow(workflowDefinition, input, correlationId: correlationId); + var startActivities = workflow.Activities.Find(startActivityIds); + + return ExecuteAsync(workflow, false, startActivities, cancellationToken); + } + + public Task RunAsync( + Variables input = default, + IEnumerable startActivityIds = default, + string correlationId = default, + CancellationToken cancellationToken = default) where T : IWorkflow, new() + { + var workflow = workflowFactory.CreateWorkflow(input, correlationId: correlationId); + var startActivities = workflow.Activities.Find(startActivityIds); + + return ExecuteAsync(workflow, false, startActivities, cancellationToken); + } + + public Task ResumeAsync( + Workflow workflow, + IEnumerable startActivities = default, + CancellationToken cancellationToken = default) + { + return ExecuteAsync(workflow, true, startActivities, cancellationToken); + } + + public Task ResumeAsync( + WorkflowInstance workflowInstance, + Variables input = null, + IEnumerable startActivityIds = default, + CancellationToken cancellationToken = default) where T : IWorkflow, new() + { + var workflow = workflowFactory.CreateWorkflow(input, workflowInstance); + var startActivities = workflow.Activities.Find(startActivityIds); + return ExecuteAsync(workflow, true, startActivities, cancellationToken); + } + + public async Task ResumeAsync( + WorkflowInstance workflowInstance, + Variables input = null, + IEnumerable startActivityIds = default, + CancellationToken cancellationToken = default) + { + var definition = await workflowRegistry.GetWorkflowDefinitionAsync( + workflowInstance.DefinitionId, + VersionOptions.SpecificVersion(workflowInstance.Version), + cancellationToken); + var workflow = workflowFactory.CreateWorkflow(definition, input, workflowInstance); + return await ExecuteAsync(workflow, true, startActivityIds, cancellationToken); + } + + public async Task> TriggerAsync( + string activityType, + Variables input = default, + string correlationId = default, + Func activityStatePredicate = default, + CancellationToken cancellationToken = default) + { + var startedExecutionContexts = await RunManyAsync( + activityType, + input, + correlationId, + activityStatePredicate, + cancellationToken + ); + + var resumedExecutionContexts = await ResumeManyAsync( + activityType, + input, + correlationId, + activityStatePredicate, + cancellationToken + ); + + return startedExecutionContexts.Concat(resumedExecutionContexts); + } + + private async Task> ResumeManyAsync( + string activityType, + Variables input = default, + string correlationId = default, + Func activityStatePredicate = default, + CancellationToken cancellationToken = default) + { + var workflowInstances = await workflowInstanceStore + .ListByBlockingActivityAsync(activityType, correlationId, cancellationToken) + .ToListAsync(); + + if (activityStatePredicate != null) + workflowInstances = workflowInstances.Where(x => activityStatePredicate(x.Item2.State)).ToList(); + + return await ResumeManyAsync( + workflowInstances, + input, + cancellationToken + ); + } + + private async Task> RunManyAsync( + string activityType, + Variables input = default, + string correlationId = default, + Func activityStatePredicate = default, + CancellationToken cancellationToken = default) + { + var workflowDefinitions = await workflowRegistry.ListByStartActivityAsync(activityType, cancellationToken); + + if (activityStatePredicate != null) + workflowDefinitions = workflowDefinitions.Where(x => activityStatePredicate(x.Item2.State)); + + workflowDefinitions = await FilterRunningSingletonsAsync( + workflowDefinitions, + cancellationToken + ); + + return await RunManyAsync(workflowDefinitions, input, correlationId, cancellationToken); + } + + private Task ExecuteAsync( + Workflow workflow, + bool resume, + IEnumerable startActivityIds = default, + CancellationToken cancellationToken = default) + { + var startActivities = startActivityIds != null + ? workflow.Activities.Find(startActivityIds) + : Enumerable.Empty(); + + return ExecuteAsync(workflow, resume, startActivities, cancellationToken); + } + + private async Task ExecuteAsync( + Workflow workflow, + bool resume, + IEnumerable startActivities = default, + CancellationToken cancellationToken = default) + { + var workflowExecutionContext = await CreateWorkflowExecutionContextAsync( + workflow, + startActivities, + cancellationToken + ); + + var start = !resume; + + while (workflowExecutionContext.HasScheduledActivities) + { + var currentActivity = workflowExecutionContext.PopScheduledActivity(); + + var result = start + ? await ExecuteActivityAsync(workflowExecutionContext, currentActivity, cancellationToken) + : await ResumeActivityAsync(workflowExecutionContext, currentActivity, cancellationToken); + + if (result == null) + break; + + await result.ExecuteAsync(this, workflowExecutionContext, cancellationToken); + + workflowExecutionContext.IsFirstPass = false; + start = true; + } + + await FinalizeWorkflowExecutionAsync(workflowExecutionContext, cancellationToken); + + return workflowExecutionContext; + } + + private async Task> RunManyAsync( + IEnumerable<(WorkflowDefinitionVersion, ActivityDefinition)> workflowDefinitions, + Variables input, + string correlationId, + CancellationToken cancellationToken1) + { + var executionContexts = new List(); + + foreach (var (workflowDefinition, activityDefinition) in workflowDefinitions) + { + var startActivityIds = workflowDefinition.Activities + .Where(x => x.Id == activityDefinition.Id) + .Select(x => x.Id); + + var workflow = workflowFactory.CreateWorkflow(workflowDefinition, input, correlationId: correlationId); + + var executionContext = await ExecuteAsync( + workflow, + false, + startActivityIds, + cancellationToken1 + ); + executionContexts.Add(executionContext); + } + + return executionContexts; + } + + private async Task> ResumeManyAsync( + IEnumerable<(WorkflowInstance, ActivityInstance)> workflowInstances, + Variables input, + CancellationToken cancellationToken) + { + var executionContexts = new List(); + var workflowInstanceGroups = workflowInstances.GroupBy(x => x.Item1); + + foreach (var workflowInstanceGroup in workflowInstanceGroups) + { + var workflowInstance = workflowInstanceGroup.Key; + + var workflowDefinition = await workflowRegistry.GetWorkflowDefinitionAsync( + workflowInstance.DefinitionId, + VersionOptions.SpecificVersion(workflowInstance.Version), + cancellationToken + ); + + var workflow = workflowFactory.CreateWorkflow(workflowDefinition, input, workflowInstance); + + foreach (var activity in workflowInstanceGroup) + { + var executionContext = await ExecuteAsync( + workflow, + true, + new[] { activity.Item2.Id }, + cancellationToken + ); + + executionContexts.Add(executionContext); + } + } + + return executionContexts; + } + + private async Task FinalizeWorkflowExecutionAsync( + WorkflowExecutionContext workflowExecutionContext, + CancellationToken cancellationToken) + { + if (!workflowExecutionContext.Workflow.BlockingActivities.Any() && + workflowExecutionContext.Workflow.IsExecuting()) + { + workflowExecutionContext.Finish(); + } + else + { + // Notify event handlers that halting activities are about to be executed. + await workflowEventHandlers.InvokeAsync( + async x => await x.InvokingHaltedActivitiesAsync(workflowExecutionContext, cancellationToken), + logger + ); + + // Invoke Halted event on activity drivers that halted the workflow. + while (workflowExecutionContext.HasScheduledHaltingActivities) + { + var currentActivity = workflowExecutionContext.PopScheduledHaltingActivity(); + var result = await ExecuteActivityHaltedAsync( + workflowExecutionContext, + currentActivity, + cancellationToken + ); + + await result.ExecuteAsync(this, workflowExecutionContext, cancellationToken); + } + } + + // Notify event handlers that workflow execution has ended. + await workflowEventHandlers.InvokeAsync( + async x => await x.WorkflowInvokedAsync(workflowExecutionContext, cancellationToken), + logger + ); + } + + private async Task ExecuteActivityAsync( + WorkflowExecutionContext workflowContext, + IActivity activity, + CancellationToken cancellationToken) + { + return await InvokeActivityAsync( + workflowContext, + activity, + async () => await activityInvoker.ExecuteAsync(workflowContext, activity, cancellationToken), + cancellationToken + ); + } + + private async Task ResumeActivityAsync( + WorkflowExecutionContext workflowContext, + IActivity activity, + CancellationToken cancellationToken) + { + return await InvokeActivityAsync( + workflowContext, + activity, + async () => await activityInvoker.ResumeAsync(workflowContext, activity, cancellationToken), + cancellationToken + ); + } + + private async Task InvokeActivityAsync( + WorkflowExecutionContext workflowContext, + IActivity activity, + Func> executeAction, + CancellationToken cancellationToken) + { + try + { + if (cancellationToken.IsCancellationRequested) + { + workflowContext.Workflow.Status = WorkflowStatus.Cancelled; + workflowContext.Workflow.FinishedAt = clock.GetCurrentInstant(); + return null; + } + + return await executeAction(); + } + catch (Exception ex) + { + FaultWorkflow(workflowContext, activity, ex); + } + + return null; + } + + private async Task ExecuteActivityHaltedAsync( + WorkflowExecutionContext workflowContext, + IActivity activity, + CancellationToken cancellationToken) + { + return await InvokeActivityAsync( + workflowContext, + activity, + async () => await activityInvoker.HaltedAsync(workflowContext, activity, cancellationToken), + cancellationToken + ); + } + + private void FaultWorkflow(WorkflowExecutionContext workflowContext, IActivity activity, Exception ex) + { + logger.LogError( + ex, + "An unhandled error occurred while executing an activity. Putting the workflow in the faulted state." + ); + workflowContext.Fault(activity, ex); + } + + private async Task CreateWorkflowExecutionContextAsync( + Workflow workflow, + IEnumerable startActivities, + CancellationToken cancellationToken) + { + var workflowExecutionContext = new WorkflowExecutionContext(workflow, clock, serviceProvider); + var startActivityList = startActivities?.ToList() ?? workflow.GetStartActivities().Take(1).ToList(); + + foreach (var startActivity in startActivityList) + { + if (await startActivity.CanExecuteAsync(workflowExecutionContext, cancellationToken)) + workflowExecutionContext.ScheduleActivity(startActivity); + } + + if (workflowExecutionContext.HasScheduledActivities) + { + workflow.BlockingActivities.RemoveWhere(startActivityList.Contains); + + if (workflowExecutionContext.Workflow.Status == WorkflowStatus.Pending) + workflowExecutionContext.Start(); + } + + return workflowExecutionContext; + } + + private async Task> FilterRunningSingletonsAsync( + IEnumerable<(WorkflowDefinitionVersion, ActivityDefinition)> workflowDefinitions, + CancellationToken cancellationToken) + { + var definitions = workflowDefinitions.ToList(); + var transients = definitions.Where(x => !x.Item1.IsSingleton).ToList(); + var singletons = definitions.Where(x => x.Item1.IsSingleton).ToList(); + var result = transients.ToList(); + + foreach (var definition in singletons) + { + var instances = await workflowInstanceStore.ListByStatusAsync( + definition.Item1.DefinitionId, + WorkflowStatus.Running, + cancellationToken + ); + + if (!instances.Any()) + { + result.Add(definition); + } + } + + return result; + } + } } \ No newline at end of file diff --git a/src/dashboard/Elsa.Dashboard/Areas/Elsa/Controllers/WorkflowDefinitionController.cs b/src/dashboard/Elsa.Dashboard/Areas/Elsa/Controllers/WorkflowDefinitionController.cs index 3b19f02c9..e40aed316 100644 --- a/src/dashboard/Elsa.Dashboard/Areas/Elsa/Controllers/WorkflowDefinitionController.cs +++ b/src/dashboard/Elsa.Dashboard/Areas/Elsa/Controllers/WorkflowDefinitionController.cs @@ -189,10 +189,10 @@ namespace Elsa.Dashboard.Areas.Elsa.Controllers return new WorkflowDefinitionListItemModel { WorkflowDefinition = workflowDefinition, - AbortedCount = instances.Count(x => x.Status == WorkflowStatus.Aborted), + AbortedCount = instances.Count(x => x.Status == WorkflowStatus.Cancelled), FaultedCount = instances.Count(x => x.Status == WorkflowStatus.Faulted), - FinishedCount = instances.Count(x => x.Status == WorkflowStatus.Finished), - ExecutingCount = instances.Count(x => x.Status == WorkflowStatus.Executing), + FinishedCount = instances.Count(x => x.Status == WorkflowStatus.Completed), + ExecutingCount = instances.Count(x => x.Status == WorkflowStatus.Running), }; } } diff --git a/src/dashboard/Elsa.Dashboard/Areas/Elsa/Views/WorkflowDefinition/Index.cshtml b/src/dashboard/Elsa.Dashboard/Areas/Elsa/Views/WorkflowDefinition/Index.cshtml index 10f59127b..f3fd30155 100644 --- a/src/dashboard/Elsa.Dashboard/Areas/Elsa/Views/WorkflowDefinition/Index.cshtml +++ b/src/dashboard/Elsa.Dashboard/Areas/Elsa/Views/WorkflowDefinition/Index.cshtml @@ -76,7 +76,7 @@ asp-action="Index" asp-controller="WorkflowInstance" asp-route-definitionId="@latest.WorkflowDefinition.DefinitionId" - asp-route-status="Executing"> + asp-route-status="Running"> @($"{latest.ExecutingCount} Executing") @@ -106,7 +106,7 @@ asp-action="Index" asp-controller="WorkflowInstance" asp-route-definitionId="@latest.WorkflowDefinition.DefinitionId" - asp-route-status="Finished"> + asp-route-status="Completed"> @($"{latest.FinishedCount} Finished") @@ -121,7 +121,7 @@ asp-action="Index" asp-controller="WorkflowInstance" asp-route-definitionId="@latest.WorkflowDefinition.DefinitionId" - asp-route-status="Aborted"> + asp-route-status="Cancelled"> @($"{latest.AbortedCount} Aborted") diff --git a/src/dashboard/Elsa.Dashboard/Extensions/WorkflowStatusExtensions.cs b/src/dashboard/Elsa.Dashboard/Extensions/WorkflowStatusExtensions.cs index d647f29ee..913523d56 100644 --- a/src/dashboard/Elsa.Dashboard/Extensions/WorkflowStatusExtensions.cs +++ b/src/dashboard/Elsa.Dashboard/Extensions/WorkflowStatusExtensions.cs @@ -7,10 +7,10 @@ namespace Elsa.Dashboard.Extensions public static string GetStatusClass(this WorkflowStatus workflowStatus) => workflowStatus switch { - WorkflowStatus.Executing => "bg-info", + WorkflowStatus.Running => "bg-info", WorkflowStatus.Faulted => "bg-warning", - WorkflowStatus.Finished => "bg-success", - WorkflowStatus.Aborted => "bg-info", + WorkflowStatus.Completed => "bg-success", + WorkflowStatus.Cancelled => "bg-info", _ => "bg-default", }; } diff --git a/src/persistence/Elsa.Persistence.DocumentDb/Services/CosmosDbWorkflowInstanceStore.cs b/src/persistence/Elsa.Persistence.DocumentDb/Services/CosmosDbWorkflowInstanceStore.cs index 0cd3edc17..26e930dc4 100644 --- a/src/persistence/Elsa.Persistence.DocumentDb/Services/CosmosDbWorkflowInstanceStore.cs +++ b/src/persistence/Elsa.Persistence.DocumentDb/Services/CosmosDbWorkflowInstanceStore.cs @@ -69,7 +69,7 @@ namespace Elsa.Persistence.DocumentDb.Services var query = client .CreateDocumentQuery(storage.CollectionUri) - .Where(x => x.Status == WorkflowStatus.Executing); + .Where(x => x.Status == WorkflowStatus.Running); if (!string.IsNullOrWhiteSpace(correlationId)) { diff --git a/src/persistence/Elsa.Persistence.EntityFrameworkCore/Services/EntityFrameworkCoreWorkflowInstanceStore.cs b/src/persistence/Elsa.Persistence.EntityFrameworkCore/Services/EntityFrameworkCoreWorkflowInstanceStore.cs index 9dc7d6b58..44725c011 100644 --- a/src/persistence/Elsa.Persistence.EntityFrameworkCore/Services/EntityFrameworkCoreWorkflowInstanceStore.cs +++ b/src/persistence/Elsa.Persistence.EntityFrameworkCore/Services/EntityFrameworkCoreWorkflowInstanceStore.cs @@ -118,7 +118,7 @@ namespace Elsa.Persistence.EntityFrameworkCore.Services .Include(x => x.BlockingActivities) .AsQueryable(); - query = query.Where(x => x.Status == WorkflowStatus.Executing); + query = query.Where(x => x.Status == WorkflowStatus.Running); if (!string.IsNullOrWhiteSpace(correlationId)) query = query.Where(x => x.CorrelationId == correlationId); diff --git a/src/persistence/Elsa.Persistence.MongoDb/Services/MongoWorkflowInstanceStore.cs b/src/persistence/Elsa.Persistence.MongoDb/Services/MongoWorkflowInstanceStore.cs index 4e349d8fd..53de7d745 100644 --- a/src/persistence/Elsa.Persistence.MongoDb/Services/MongoWorkflowInstanceStore.cs +++ b/src/persistence/Elsa.Persistence.MongoDb/Services/MongoWorkflowInstanceStore.cs @@ -70,7 +70,7 @@ namespace Elsa.Persistence.MongoDb.Services { var query = collection.AsQueryable(); - query = query.Where(x => x.Status == WorkflowStatus.Executing); + query = query.Where(x => x.Status == WorkflowStatus.Running); if (!string.IsNullOrWhiteSpace(correlationId)) query = query.Where(x => x.CorrelationId == correlationId); diff --git a/src/persistence/Elsa.Persistence.YesSql/Services/YesSqlWorkflowInstanceStore.cs b/src/persistence/Elsa.Persistence.YesSql/Services/YesSqlWorkflowInstanceStore.cs index 414f89747..0d4afe885 100644 --- a/src/persistence/Elsa.Persistence.YesSql/Services/YesSqlWorkflowInstanceStore.cs +++ b/src/persistence/Elsa.Persistence.YesSql/Services/YesSqlWorkflowInstanceStore.cs @@ -78,7 +78,7 @@ namespace Elsa.Persistence.YesSql.Services { var query = session.Query(); - query = query.Where(x => x.WorkflowStatus == WorkflowStatus.Executing); + query = query.Where(x => x.WorkflowStatus == WorkflowStatus.Running); if (!string.IsNullOrWhiteSpace(correlationId)) query = query.Where(x => x.CorrelationId == correlationId); diff --git a/src/samples/Sample01/Program.cs b/src/samples/Sample01/Program.cs index 76cb9ddce..0cea22c2a 100644 --- a/src/samples/Sample01/Program.cs +++ b/src/samples/Sample01/Program.cs @@ -21,8 +21,8 @@ namespace Sample01 .BuildServiceProvider(); // Invoke the workflow. - var invoker = services.GetService(); - await invoker.StartAsync(); + var invoker = services.GetService(); + await invoker.RunAsync(); Console.ReadLine(); } diff --git a/src/samples/Sample02/Program.cs b/src/samples/Sample02/Program.cs index 5dcfb9dbd..82ed6035f 100644 --- a/src/samples/Sample02/Program.cs +++ b/src/samples/Sample02/Program.cs @@ -30,8 +30,8 @@ namespace Sample02 .Build(); // Start the workflow. - var invoker = services.GetService(); - await invoker.StartAsync(workflowDefinition); + var invoker = services.GetService(); + await invoker.RunAsync(workflowDefinition); Console.ReadLine(); } diff --git a/src/samples/Sample03/Program.cs b/src/samples/Sample03/Program.cs index 71f31f723..e6492c32e 100644 --- a/src/samples/Sample03/Program.cs +++ b/src/samples/Sample03/Program.cs @@ -39,8 +39,8 @@ namespace Sample03 }; // Run the workflow. - var invoker = services.GetService(); - await invoker.StartAsync(workflowDefinition); + var invoker = services.GetService(); + await invoker.RunAsync(workflowDefinition); Console.ReadLine(); } diff --git a/src/samples/Sample04/Program.cs b/src/samples/Sample04/Program.cs index 1881030ee..5afedc094 100644 --- a/src/samples/Sample04/Program.cs +++ b/src/samples/Sample04/Program.cs @@ -31,8 +31,8 @@ namespace Sample04 var workflow = workflowFactory.CreateWorkflow(); // Start the workflow. - var invoker = services.GetService(); - await invoker.StartAsync(workflow); + var invoker = services.GetService(); + await invoker.RunAsync(workflow); Console.WriteLine("Workflow has ended. Here are the activities that have executed:"); foreach (var logEntry in workflow.ExecutionLog) diff --git a/src/samples/Sample09/Program.cs b/src/samples/Sample09/Program.cs index 6dd567f85..02b6b34ed 100644 --- a/src/samples/Sample09/Program.cs +++ b/src/samples/Sample09/Program.cs @@ -22,9 +22,9 @@ namespace Sample09 var services = BuildServices(); var serializer = services.GetRequiredService(); var workflow = serializer.Deserialize(json, JsonTokenFormatter.FormatName); - var invoker = services.GetRequiredService(); + var invoker = services.GetRequiredService(); - await invoker.StartAsync(workflow); + await invoker.RunAsync(workflow); } private static IServiceProvider BuildServices() diff --git a/src/samples/Sample10/Program.cs b/src/samples/Sample10/Program.cs index 8cf8c85f4..d9c336c9d 100644 --- a/src/samples/Sample10/Program.cs +++ b/src/samples/Sample10/Program.cs @@ -50,8 +50,8 @@ namespace Sample10 VersionOptions.Latest); // Execute the workflow. - var invoker = scope.ServiceProvider.GetRequiredService(); - var executionContext = await invoker.StartAsync(workflowDefinition); + var invoker = scope.ServiceProvider.GetRequiredService(); + var executionContext = await invoker.RunAsync(workflowDefinition); // Persist the workflow instance. var instanceStore = scope.ServiceProvider.GetRequiredService(); diff --git a/src/samples/Sample11/Program.cs b/src/samples/Sample11/Program.cs index 7e2d032f1..d48faaf8a 100644 --- a/src/samples/Sample11/Program.cs +++ b/src/samples/Sample11/Program.cs @@ -20,13 +20,13 @@ namespace Sample11 var services = BuildServices(); var registry = services.GetService(); var workflowDefinition = await registry.GetWorkflowDefinitionAsync(); - var invoker = services.GetRequiredService(); + var invoker = services.GetRequiredService(); Console.WriteLine("How many workflow instances should be started? Enter a number:"); var instanceCount = int.Parse(Console.ReadLine()); for (var i = 0; i < instanceCount; i++) - await invoker.StartAsync(workflowDefinition, correlationId: $"document {i + 1}"); + await invoker.RunAsync(workflowDefinition, correlationId: $"document {i + 1}"); var retry = true; diff --git a/src/samples/Sample12/Program.cs b/src/samples/Sample12/Program.cs index 9c2eb906b..b3d278d9e 100644 --- a/src/samples/Sample12/Program.cs +++ b/src/samples/Sample12/Program.cs @@ -22,11 +22,11 @@ namespace Sample12 var services = BuildServices(); var registry = services.GetService(); var workflowDefinition = await registry.GetWorkflowDefinitionAsync(); - var invoker = services.GetRequiredService(); + var invoker = services.GetRequiredService(); // Start the workflow. var correlationId = Guid.NewGuid().ToString("N"); - await invoker.StartAsync(workflowDefinition, correlationId: correlationId); + await invoker.RunAsync(workflowDefinition, correlationId: correlationId); WorkflowExecutionContext executionContext; do diff --git a/src/samples/Sample13/Program.cs b/src/samples/Sample13/Program.cs index 841571ec4..144bbe0ed 100644 --- a/src/samples/Sample13/Program.cs +++ b/src/samples/Sample13/Program.cs @@ -27,8 +27,8 @@ namespace Sample13 var workflow = workflowFactory.CreateWorkflow(); // Start the workflow. - var invoker = services.GetService(); - await invoker.StartAsync(workflow); + var invoker = services.GetService(); + await invoker.RunAsync(workflow); Console.ReadLine(); } diff --git a/src/samples/Sample14/Program.cs b/src/samples/Sample14/Program.cs index 291de3f84..90d8b57f2 100644 --- a/src/samples/Sample14/Program.cs +++ b/src/samples/Sample14/Program.cs @@ -54,8 +54,8 @@ namespace Sample14 VersionOptions.Latest); // Execute the workflow. - var invoker = scope.ServiceProvider.GetRequiredService(); - var executionContext = await invoker.StartAsync(workflowDefinition); + var invoker = scope.ServiceProvider.GetRequiredService(); + var executionContext = await invoker.RunAsync(workflowDefinition); // Persist the workflow instance. var instanceStore = scope.ServiceProvider.GetRequiredService(); diff --git a/src/samples/Sample15/Program.cs b/src/samples/Sample15/Program.cs index 30b4a103d..e88a65626 100644 --- a/src/samples/Sample15/Program.cs +++ b/src/samples/Sample15/Program.cs @@ -41,8 +41,8 @@ namespace Sample15 VersionOptions.Latest); // Execute the workflow. - var invoker = scope.ServiceProvider.GetRequiredService(); - var executionContext = await invoker.StartAsync(workflowDefinition); + var invoker = scope.ServiceProvider.GetRequiredService(); + var executionContext = await invoker.RunAsync(workflowDefinition); // Persist the workflow instance. var instanceStore = scope.ServiceProvider.GetRequiredService(); diff --git a/src/samples/Sample17/Program.cs b/src/samples/Sample17/Program.cs index 6ebacae65..7b7b7583e 100644 --- a/src/samples/Sample17/Program.cs +++ b/src/samples/Sample17/Program.cs @@ -13,8 +13,8 @@ namespace Sample17 private static async Task Main(string[] args) { var services = BuildServices(); - var workflowInvoker = services.GetRequiredService(); - var workflowExecutionContext = await workflowInvoker.StartAsync(); + var workflowInvoker = services.GetRequiredService(); + var workflowExecutionContext = await workflowInvoker.RunAsync(); var document = workflowExecutionContext.CurrentScope.GetVariable("Document"); Console.WriteLine("Created document: {0}", document); diff --git a/src/samples/Sample18/Program.cs b/src/samples/Sample18/Program.cs index 85de0d738..c565a57d5 100644 --- a/src/samples/Sample18/Program.cs +++ b/src/samples/Sample18/Program.cs @@ -31,8 +31,8 @@ namespace Sample18 { await host.StartAsync(); - var workflowInvoker = host.Services.GetRequiredService(); - await workflowInvoker.StartAsync(); + var workflowInvoker = host.Services.GetRequiredService(); + await workflowInvoker.RunAsync(); await host.WaitForShutdownAsync(); } diff --git a/src/samples/Sample20/Program.cs b/src/samples/Sample20/Program.cs index 2ec9078e6..41109d061 100644 --- a/src/samples/Sample20/Program.cs +++ b/src/samples/Sample20/Program.cs @@ -29,9 +29,9 @@ namespace Sample20 .BuildServiceProvider(); // Invoke the workflows. - var invoker = services.GetService(); - var executionContext1 = await invoker.StartAsync(); - var executionContext2 = await invoker.StartAsync(); + var invoker = services.GetService(); + var executionContext1 = await invoker.RunAsync(); + var executionContext2 = await invoker.RunAsync(); var serializer = services.GetRequiredService(); diff --git a/src/server/Elsa.Server.GraphQL/Mutations/RunWorkflow.cs b/src/server/Elsa.Server.GraphQL/Mutations/RunWorkflow.cs index 1ac3a2f3c..d088e66c6 100644 --- a/src/server/Elsa.Server.GraphQL/Mutations/RunWorkflow.cs +++ b/src/server/Elsa.Server.GraphQL/Mutations/RunWorkflow.cs @@ -9,12 +9,12 @@ namespace Elsa.Server.GraphQL.Mutations { public class RunWorkflow : IMutationProvider { - private readonly IWorkflowInvoker workflowInvoker; + private readonly IWorkflowRunner workflowRunner; private readonly IWorkflowDefinitionStore workflowDefinitionStore; - public RunWorkflow(IWorkflowInvoker workflowInvoker, IWorkflowDefinitionStore workflowDefinitionStore) + public RunWorkflow(IWorkflowRunner workflowRunner, IWorkflowDefinitionStore workflowDefinitionStore) { - this.workflowInvoker = workflowInvoker; + this.workflowRunner = workflowRunner; this.workflowDefinitionStore = workflowDefinitionStore; } @@ -36,7 +36,7 @@ namespace Elsa.Server.GraphQL.Mutations return null; var correlationId = context.GetArgument("correlationId"); - var executionContext = await workflowInvoker.StartAsync(workflowDefinition, correlationId: correlationId, cancellationToken: context.CancellationToken); + var executionContext = await workflowRunner.RunAsync(workflowDefinition, correlationId: correlationId, cancellationToken: context.CancellationToken); return executionContext.Workflow.ToInstance(); }); }