From d890c668cc855df4e89441fe3780ded45c8fb70b Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Tue, 24 Nov 2020 19:54:16 +0100 Subject: [PATCH] Expose WorkflowExecutionContext to Workflow Context providers --- .../Services/Models/IWorkflowBlueprint.cs | 1 + .../Services/Models/LoadWorkflowContext.cs | 10 +++++----- src/core/Elsa.Core/Services/WorkflowRunner.cs | 19 +++++++++++-------- .../Elsa.Core/Triggers/WorkflowSelector.cs | 9 +++++---- 4 files changed, 22 insertions(+), 17 deletions(-) diff --git a/src/core/Elsa.Abstractions/Services/Models/IWorkflowBlueprint.cs b/src/core/Elsa.Abstractions/Services/Models/IWorkflowBlueprint.cs index ed8e0839d..8a6616f71 100644 --- a/src/core/Elsa.Abstractions/Services/Models/IWorkflowBlueprint.cs +++ b/src/core/Elsa.Abstractions/Services/Models/IWorkflowBlueprint.cs @@ -16,6 +16,7 @@ namespace Elsa.Services.Models /// An optional context type around which this workflow revolves. For example, a document, a leave request or a job application. /// public WorkflowContextOptions? ContextOptions { get; set; } + public WorkflowPersistenceBehavior PersistenceBehavior { get; } public bool DeleteCompletedInstances { get; } } diff --git a/src/core/Elsa.Abstractions/Services/Models/LoadWorkflowContext.cs b/src/core/Elsa.Abstractions/Services/Models/LoadWorkflowContext.cs index 0c859602e..a22cd8f00 100644 --- a/src/core/Elsa.Abstractions/Services/Models/LoadWorkflowContext.cs +++ b/src/core/Elsa.Abstractions/Services/Models/LoadWorkflowContext.cs @@ -5,14 +5,14 @@ namespace Elsa.Services.Models { public class LoadWorkflowContext { - public LoadWorkflowContext(IWorkflowBlueprint workflowBlueprint, WorkflowInstance workflowInstance) + public LoadWorkflowContext(WorkflowExecutionContext workflowExecutionContext) { - WorkflowBlueprint = workflowBlueprint; - WorkflowInstance = workflowInstance; + WorkflowExecutionContext = workflowExecutionContext; } - public IWorkflowBlueprint WorkflowBlueprint { get; } - public WorkflowInstance WorkflowInstance { get; } + public WorkflowExecutionContext WorkflowExecutionContext { get; } + public IWorkflowBlueprint WorkflowBlueprint => WorkflowExecutionContext.WorkflowBlueprint; + public WorkflowInstance WorkflowInstance => WorkflowExecutionContext.WorkflowInstance; public Type ContextType => WorkflowBlueprint.ContextOptions!.ContextType; public string ContextId => WorkflowInstance.ContextId!; diff --git a/src/core/Elsa.Core/Services/WorkflowRunner.cs b/src/core/Elsa.Core/Services/WorkflowRunner.cs index bb7d10ce3..58ec86ef2 100644 --- a/src/core/Elsa.Core/Services/WorkflowRunner.cs +++ b/src/core/Elsa.Core/Services/WorkflowRunner.cs @@ -156,8 +156,9 @@ namespace Elsa.Services object? input = default, CancellationToken cancellationToken = default) { - var workflowContext = await LoadWorkflowContextAsync(workflowBlueprint, workflowInstance, WorkflowContextFidelity.Burst, false, cancellationToken); - var workflowExecutionContext = CreateWorkflowExecutionContext(workflowBlueprint, workflowInstance, input, workflowContext, _serviceProvider); + var workflowExecutionContext = CreateWorkflowExecutionContext(workflowBlueprint, workflowInstance, input, _serviceProvider); + workflowExecutionContext.WorkflowContext = await LoadWorkflowContextAsync(workflowExecutionContext, WorkflowContextFidelity.Burst, false, cancellationToken); + var activity = activityId != null ? workflowBlueprint.GetActivity(activityId) : default; switch (workflowExecutionContext.Status) @@ -193,12 +194,15 @@ namespace Elsa.Services return workflowExecutionContext.WorkflowInstance; } - private async ValueTask LoadWorkflowContextAsync(IWorkflowBlueprint workflowBlueprint, WorkflowInstance workflowInstance, WorkflowContextFidelity fidelity, bool always, CancellationToken cancellationToken) + private async ValueTask LoadWorkflowContextAsync(WorkflowExecutionContext workflowExecutionContext, WorkflowContextFidelity fidelity, bool always, CancellationToken cancellationToken) { + var workflowInstance = workflowExecutionContext.WorkflowInstance; + var workflowBlueprint = workflowExecutionContext.WorkflowBlueprint; + if (!always && (workflowInstance.ContextId == null || workflowBlueprint.ContextOptions == null || workflowBlueprint.ContextOptions.ContextFidelity != fidelity)) return null; - var context = new LoadWorkflowContext(workflowBlueprint, workflowInstance); + var context = new LoadWorkflowContext(workflowExecutionContext); return await _workflowContextManager.LoadContext(context, cancellationToken); } @@ -257,7 +261,6 @@ namespace Elsa.Services using var scope = _serviceProvider.CreateScope(); var serviceProvider = scope.ServiceProvider; var workflowBlueprint = workflowExecutionContext.WorkflowBlueprint; - var workflowInstance = workflowExecutionContext.WorkflowInstance; while (workflowExecutionContext.HasScheduledActivities) { @@ -266,7 +269,7 @@ namespace Elsa.Services var activityBlueprint = workflowBlueprint.GetActivity(currentActivityId)!; if (workflowBlueprint.ContextOptions?.ContextFidelity == WorkflowContextFidelity.Activity || activityBlueprint.LoadWorkflowContext) - workflowExecutionContext.WorkflowContext = await LoadWorkflowContextAsync(workflowBlueprint, workflowInstance, WorkflowContextFidelity.Activity, activityBlueprint.LoadWorkflowContext, cancellationToken); + workflowExecutionContext.WorkflowContext = await LoadWorkflowContextAsync(workflowExecutionContext, WorkflowContextFidelity.Activity, activityBlueprint.LoadWorkflowContext, cancellationToken); var activityExecutionContext = new ActivityExecutionContext(workflowExecutionContext, serviceProvider, activityBlueprint, scheduledActivity.Input); var activity = await activityBlueprint.CreateActivityAsync(activityExecutionContext, cancellationToken); @@ -297,7 +300,7 @@ namespace Elsa.Services workflowExecutionContext.Complete(); } - private static WorkflowExecutionContext CreateWorkflowExecutionContext(IWorkflowBlueprint workflowBlueprint, WorkflowInstance workflowInstance, object? input, object? workflowContext, IServiceProvider serviceProvider) => - new WorkflowExecutionContext(serviceProvider, workflowBlueprint, workflowInstance, input, workflowContext); + private static WorkflowExecutionContext CreateWorkflowExecutionContext(IWorkflowBlueprint workflowBlueprint, WorkflowInstance workflowInstance, object? input, IServiceProvider serviceProvider) => + new WorkflowExecutionContext(serviceProvider, workflowBlueprint, workflowInstance, input); } } \ No newline at end of file diff --git a/src/core/Elsa.Core/Triggers/WorkflowSelector.cs b/src/core/Elsa.Core/Triggers/WorkflowSelector.cs index ccf385ce7..111caa54b 100644 --- a/src/core/Elsa.Core/Triggers/WorkflowSelector.cs +++ b/src/core/Elsa.Core/Triggers/WorkflowSelector.cs @@ -97,7 +97,8 @@ namespace Elsa.Triggers Func evaluate) { var descriptors = dictionary.SelectMany(x => x.Value); - return from descriptor in descriptors + return + from descriptor in descriptors let workflow = descriptor.WorkflowBlueprint where workflow.IsPublished && workflow.IsEnabled let workflowInstanceId = descriptor.WorkflowInstanceId @@ -119,7 +120,7 @@ namespace Elsa.Triggers return descriptors .GroupBy(x => x.WorkflowBlueprint.Id) - .ToDictionary(x => x.Key, x => (ICollection)x.ToList()); + .ToDictionary(x => x.Key, x => (ICollection) x.ToList()); } private async Task> BuildDescriptorsForAsync(IWorkflowBlueprint workflowBlueprint, CancellationToken cancellationToken) @@ -158,8 +159,8 @@ namespace Elsa.Triggers { var providers = _triggerProviders.ToList(); var descriptors = new List(); - var workflowContext = workflowBlueprint.ContextOptions != null ? await _workflowContextManager.LoadContext(new LoadWorkflowContext(workflowBlueprint, workflowInstance), cancellationToken) : default; - var workflowExecutionContext = new WorkflowExecutionContext(_serviceProvider, workflowBlueprint, workflowInstance, default, workflowContext); + var workflowExecutionContext = new WorkflowExecutionContext(_serviceProvider, workflowBlueprint, workflowInstance, default); + workflowExecutionContext.WorkflowContext = workflowBlueprint.ContextOptions != null ? await _workflowContextManager.LoadContext(new LoadWorkflowContext(workflowExecutionContext), cancellationToken) : default; foreach (var blockingActivity in blockingActivities) {