Optimize workflow registry loading by only considering older versions for which there are non-finished workflow instances pending

This commit is contained in:
Sipke Schoorstra 2021-04-15 21:38:10 +02:00
parent 7fa0a3b8d7
commit 937b861359
2 changed files with 17 additions and 12 deletions

View file

@ -65,7 +65,6 @@ namespace Elsa.Activities.AzureServiceBus.Services
using var scope = _scopeFactory.CreateScope();
var workflowRegistry = scope.ServiceProvider.GetRequiredService<IWorkflowRegistry>();
var workflowBlueprintReflector = scope.ServiceProvider.GetRequiredService<IWorkflowBlueprintReflector>();
var workflowInstanceStore = scope.ServiceProvider.GetRequiredService<IWorkflowInstanceStore>();
var workflows = await workflowRegistry.ListAsync(cancellationToken);
var query =
@ -76,10 +75,6 @@ namespace Elsa.Activities.AzureServiceBus.Services
foreach (var workflow in query)
{
// If a workflow is not published, only consider it for processing if it has at least one non-ended workflow instance.
if (!workflow.IsPublished && !await WorkflowHasNonFinishedWorkflowsAsync(workflow, workflowInstanceStore, cancellationToken))
continue;
var workflowBlueprintWrapper = await workflowBlueprintReflector.ReflectAsync(scope.ServiceProvider, workflow, cancellationToken);
foreach (var activity in workflowBlueprintWrapper.Filter<AzureServiceBusQueueMessageReceived>())
@ -102,11 +97,5 @@ namespace Elsa.Activities.AzureServiceBus.Services
}
}
}
private static async Task<bool> WorkflowHasNonFinishedWorkflowsAsync(IWorkflowBlueprint workflowBlueprint, IWorkflowInstanceStore workflowInstanceStore, CancellationToken cancellationToken)
{
var count = await workflowInstanceStore.CountAsync(new NonFinalizedWorkflowSpecification().WithWorkflowDefinition(workflowBlueprint.Id), cancellationToken);
return count > 0;
}
}
}

View file

@ -5,6 +5,8 @@ using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using Elsa.Models;
using Elsa.Persistence;
using Elsa.Persistence.Specifications.WorkflowInstances;
using Elsa.Services.Models;
using Open.Linq.AsyncExtensions;
@ -13,10 +15,12 @@ namespace Elsa.Services
public class WorkflowRegistry : IWorkflowRegistry
{
private readonly IEnumerable<IWorkflowProvider> _workflowProviders;
private readonly IWorkflowInstanceStore _workflowInstanceStore;
public WorkflowRegistry(IEnumerable<IWorkflowProvider> workflowProviders)
public WorkflowRegistry(IEnumerable<IWorkflowProvider> workflowProviders, IWorkflowInstanceStore workflowInstanceStore)
{
_workflowProviders = workflowProviders;
_workflowInstanceStore = workflowInstanceStore;
}
public async Task<IEnumerable<IWorkflowBlueprint>> ListAsync(CancellationToken cancellationToken) => await GetWorkflowsInternalAsync(cancellationToken).ToListAsync(cancellationToken);
@ -36,7 +40,19 @@ namespace Elsa.Services
foreach (var provider in providers)
await foreach (var workflow in provider.GetWorkflowsAsync(cancellationToken).WithCancellation(cancellationToken))
{
// If a workflow is not published, only consider it for processing if it has at least one non-ended workflow instance.
if (!workflow.IsPublished && !await WorkflowHasNonFinishedWorkflowsAsync(workflow, cancellationToken))
continue;
yield return workflow;
}
}
private async Task<bool> WorkflowHasNonFinishedWorkflowsAsync(IWorkflowBlueprint workflowBlueprint, CancellationToken cancellationToken)
{
var count = await _workflowInstanceStore.CountAsync(new NonFinalizedWorkflowSpecification().WithWorkflowDefinition(workflowBlueprint.Id), cancellationToken);
return count > 0;
}
}
}