< 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
29%
Covered lines: 18
Uncovered lines: 44
Coverable lines: 62
Total lines: 114
Line coverage: 29%
Branch coverage
13%
Covered branches: 4
Total branches: 30
Branch coverage: 13.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()0%4260%
DispatchAsync()0%4260%
TryGetWorkflowExecutionContext(...)50%5466.66%
GetOutbox()100%210%

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>
 47218public class TransactionalWorkflowDispatcher(
 47219    IWorkflowDispatcher decoratedService,
 47220    IServiceProvider serviceProvider,
 47221    IWorkflowDispatchOutboxAccessor outboxAccessor,
 47222    INotificationSender notificationSender,
 47223    IIdentityGenerator identityGenerator,
 47224    IOptions<WorkflowDispatcherOptions> options,
 47225    ITenantAccessor? tenantAccessor = null) : IWorkflowDispatcher
 26{
 27    /// <inheritdoc />
 28    public async Task<DispatchWorkflowResponse> DispatchAsync(DispatchWorkflowDefinitionRequest request, DispatchWorkflo
 29    {
 2730        if (!TryGetWorkflowExecutionContext(out var context))
 2731            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;
 2746    }
 47
 48    /// <inheritdoc />
 49    public async Task<DispatchWorkflowResponse> DispatchAsync(DispatchWorkflowInstanceRequest request, DispatchWorkflowO
 50    {
 151        if (!TryGetWorkflowExecutionContext(out var context))
 152            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;
 166    }
 67
 68    /// <inheritdoc />
 69    public async Task<DispatchWorkflowResponse> DispatchAsync(DispatchTriggerWorkflowsRequest request, DispatchWorkflowO
 70    {
 071        if (!TryGetWorkflowExecutionContext(out var context))
 072            return await decoratedService.DispatchAsync(request, dispatchOptions, cancellationToken);
 73
 074        await GetOutbox().EnqueueAsync(context, new()
 075        {
 076            TenantId = tenantAccessor?.Tenant?.Id,
 077            Kind = WorkflowDispatchOutboxItemKind.TriggerWorkflows,
 078            TriggerWorkflowsCommand = WorkflowDispatchCommandFactory.CreateCommand(request)
 079        }, cancellationToken);
 80
 081        return DispatchWorkflowResponse.Success();
 082    }
 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    {
 28102        var currentContext = outboxAccessor.WorkflowExecutionContext;
 28103        if (!options.Value.UseTransactionalOutbox || currentContext == null)
 104        {
 28105            context = null;
 28106            return false;
 107        }
 108
 0109        context = currentContext;
 0110        return true;
 111    }
 112
 0113    private IWorkflowDispatchOutbox GetOutbox() => serviceProvider.GetRequiredService<IWorkflowDispatchOutbox>();
 114}