< Summary

Information
Class: Elsa.Workflows.Runtime.TransactionalWorkflowDispatcher
Assembly: Elsa.Workflows.Runtime
File(s): /home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Workflows.Runtime/Services/TransactionalWorkflowDispatcher.cs
Line coverage
50%
Covered lines: 31
Uncovered lines: 31
Coverable lines: 62
Total lines: 114
Line coverage: 50%
Branch coverage
33%
Covered branches: 10
Total branches: 30
Branch coverage: 33.3%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
DispatchAsync()12.5%39821.42%
DispatchAsync()16.66%22623.07%
DispatchAsync()66.66%66100%
DispatchAsync()0%4260%
TryGetWorkflowExecutionContext(...)100%44100%
GetOutbox()100%11100%

File(s)

/home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Workflows.Runtime/Services/TransactionalWorkflowDispatcher.cs

#LineLine coverage
 1using System.Diagnostics.CodeAnalysis;
 2using Elsa.Common;
 3using Elsa.Common.Multitenancy;
 4using Elsa.Mediator.Contracts;
 5using Elsa.Workflows.Runtime.Models;
 6using Elsa.Workflows.Runtime.Notifications;
 7using Elsa.Workflows.Runtime.Options;
 8using Elsa.Workflows.Runtime.Requests;
 9using Elsa.Workflows.Runtime.Responses;
 10using Microsoft.Extensions.DependencyInjection;
 11using Microsoft.Extensions.Options;
 12
 13namespace Elsa.Workflows.Runtime;
 14
 15/// <summary>
 16/// Writes workflow dispatch commands to a durable outbox while a workflow execution is in progress.
 17/// </summary>
 50818public class TransactionalWorkflowDispatcher(
 50819    IWorkflowDispatcher decoratedService,
 50820    IServiceProvider serviceProvider,
 50821    IWorkflowDispatchOutboxAccessor outboxAccessor,
 50822    INotificationSender notificationSender,
 50823    IIdentityGenerator identityGenerator,
 50824    IOptions<WorkflowDispatcherOptions> options,
 50825    ITenantAccessor? tenantAccessor = null) : IWorkflowDispatcher
 26{
 27    /// <inheritdoc />
 28    public async Task<DispatchWorkflowResponse> DispatchAsync(DispatchWorkflowDefinitionRequest request, DispatchWorkflo
 29    {
 3730        if (!TryGetWorkflowExecutionContext(out var context))
 3731            return await decoratedService.DispatchAsync(request, dispatchOptions, cancellationToken);
 32
 033        await notificationSender.SendAsync(new WorkflowDefinitionDispatching(request), cancellationToken);
 034        var generatedInstanceId = string.IsNullOrWhiteSpace(request.InstanceId) ? identityGenerator.GenerateId() : null;
 35
 036        await GetOutbox().EnqueueAsync(context, new()
 037        {
 038            TenantId = tenantAccessor?.Tenant?.Id,
 039            Kind = WorkflowDispatchOutboxItemKind.WorkflowDefinition,
 040            WorkflowDefinitionCommand = WorkflowDispatchCommandFactory.CreateCommand(request, generatedInstanceId)
 041        }, cancellationToken);
 42
 043        var response = DispatchWorkflowResponse.Success();
 044        await notificationSender.SendAsync(new WorkflowDefinitionDispatched(request, response), cancellationToken);
 045        return response;
 3746    }
 47
 48    /// <inheritdoc />
 49    public async Task<DispatchWorkflowResponse> DispatchAsync(DispatchWorkflowInstanceRequest request, DispatchWorkflowO
 50    {
 251        if (!TryGetWorkflowExecutionContext(out var context))
 252            return await decoratedService.DispatchAsync(request, dispatchOptions, cancellationToken);
 53
 054        await notificationSender.SendAsync(new WorkflowInstanceDispatching(request), cancellationToken);
 55
 056        await GetOutbox().EnqueueAsync(context, new()
 057        {
 058            TenantId = tenantAccessor?.Tenant?.Id,
 059            Kind = WorkflowDispatchOutboxItemKind.WorkflowInstance,
 060            WorkflowInstanceCommand = WorkflowDispatchCommandFactory.CreateCommand(request)
 061        }, cancellationToken);
 62
 063        var response = DispatchWorkflowResponse.Success();
 064        await notificationSender.SendAsync(new WorkflowInstanceDispatched(request, response), cancellationToken);
 065        return response;
 266    }
 67
 68    /// <inheritdoc />
 69    public async Task<DispatchWorkflowResponse> DispatchAsync(DispatchTriggerWorkflowsRequest request, DispatchWorkflowO
 70    {
 871        if (!TryGetWorkflowExecutionContext(out var context))
 772            return await decoratedService.DispatchAsync(request, dispatchOptions, cancellationToken);
 73
 174        await GetOutbox().EnqueueAsync(context, new()
 175        {
 176            TenantId = tenantAccessor?.Tenant?.Id,
 177            Kind = WorkflowDispatchOutboxItemKind.TriggerWorkflows,
 178            TriggerWorkflowsCommand = WorkflowDispatchCommandFactory.CreateCommand(request)
 179        }, cancellationToken);
 80
 181        return DispatchWorkflowResponse.Success();
 882    }
 83
 84    /// <inheritdoc />
 85    public async Task<DispatchWorkflowResponse> DispatchAsync(DispatchResumeWorkflowsRequest request, DispatchWorkflowOp
 86    {
 087        if (!TryGetWorkflowExecutionContext(out var context))
 088            return await decoratedService.DispatchAsync(request, dispatchOptions, cancellationToken);
 89
 090        await GetOutbox().EnqueueAsync(context, new()
 091        {
 092            TenantId = tenantAccessor?.Tenant?.Id,
 093            Kind = WorkflowDispatchOutboxItemKind.ResumeWorkflows,
 094            ResumeWorkflowsCommand = WorkflowDispatchCommandFactory.CreateCommand(request)
 095        }, cancellationToken);
 96
 097        return DispatchWorkflowResponse.Success();
 098    }
 99
 100    private bool TryGetWorkflowExecutionContext([NotNullWhen(true)] out WorkflowExecutionContext? context)
 101    {
 47102        var currentContext = outboxAccessor.WorkflowExecutionContext;
 47103        if (!options.Value.UseTransactionalOutbox || currentContext == null)
 104        {
 46105            context = null;
 46106            return false;
 107        }
 108
 1109        context = currentContext;
 1110        return true;
 111    }
 112
 1113    private IWorkflowDispatchOutbox GetOutbox() => serviceProvider.GetRequiredService<IWorkflowDispatchOutbox>();
 114}