< Summary

Information
Class: Elsa.Workflows.Runtime.StimulusSender
Assembly: Elsa.Workflows.Runtime
File(s): /home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Workflows.Runtime/Services/StimulusSender.cs
Line coverage
97%
Covered lines: 77
Uncovered lines: 2
Coverable lines: 79
Total lines: 129
Line coverage: 97.4%
Branch coverage
65%
Covered branches: 29
Total branches: 44
Branch coverage: 65.9%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
SendAsync(...)50%22100%
SendAsync()100%88100%
TriggerNewWorkflowsAsync()64.28%141492.59%
ResumeExistingWorkflowsAsync()55%2020100%

File(s)

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

#LineLine coverage
 1using Elsa.Workflows.Runtime.Filters;
 2using Elsa.Workflows.Runtime.Messages;
 3using Elsa.Workflows.Runtime.Results;
 4using Microsoft.Extensions.Logging;
 5using Open.Linq.AsyncExtensions;
 6
 7namespace Elsa.Workflows.Runtime;
 8
 9/// <inheritdoc />
 5710public class StimulusSender(
 5711    IStimulusHasher stimulusHasher,
 5712    ITriggerBoundWorkflowService triggerBoundWorkflowService,
 5713    IWorkflowResumer workflowResumer,
 5714    IBookmarkQueue bookmarkQueue,
 5715    ITriggerInvoker triggerInvoker,
 5716    ILogger<StimulusSender> logger) : IStimulusSender
 17{
 18    /// <inheritdoc />
 19    public Task<SendStimulusResult> SendAsync(string activityTypeName, object stimulus, StimulusMetadata? metadata = nul
 20    {
 621        var stimulusHash = stimulusHasher.Hash(activityTypeName, stimulus, metadata?.ActivityInstanceId);
 622        return SendAsync(stimulusHash, metadata, cancellationToken);
 23    }
 24
 25    /// <inheritdoc />
 26    public async Task<SendStimulusResult> SendAsync(string stimulusHash, StimulusMetadata? metadata = null, Cancellation
 27    {
 628        var responses = new List<RunWorkflowInstanceResponse>();
 29
 630        if (metadata == null || (metadata.WorkflowInstanceId == null && metadata.BookmarkId == null && metadata.Activity
 31        {
 532            var triggered = await TriggerNewWorkflowsAsync(stimulusHash, metadata, cancellationToken);
 533            responses.AddRange(triggered);
 34        }
 35
 636        var resumed = await ResumeExistingWorkflowsAsync(stimulusHash, metadata, cancellationToken);
 637        responses.AddRange(resumed);
 638        return new(responses);
 639    }
 40
 41    private async Task<ICollection<RunWorkflowInstanceResponse>> TriggerNewWorkflowsAsync(string stimulusHash, StimulusM
 42    {
 543        var triggerBoundWorkflows = await triggerBoundWorkflowService.FindManyAsync(stimulusHash, cancellationToken).ToL
 544        var correlationId = metadata?.CorrelationId;
 545        var input = metadata?.Input;
 546        var properties = metadata?.Properties;
 547        var parentId = metadata?.ParentWorkflowInstanceId;
 548        var responses = new List<RunWorkflowInstanceResponse>();
 49
 2050        foreach (var triggerBoundWorkflow in triggerBoundWorkflows)
 51        {
 552            var workflowGraph = triggerBoundWorkflow.WorkflowGraph;
 553            var workflow = workflowGraph.Workflow;
 54
 2055            foreach (var trigger in triggerBoundWorkflow.Triggers)
 56            {
 557                var triggerRequest = new InvokeTriggerRequest
 558                {
 559                    CorrelationId = correlationId,
 560                    Workflow = workflow,
 561                    ActivityId = trigger.ActivityId,
 562                    Input = input,
 563                    Properties = properties,
 564                    ParentWorkflowInstanceId = parentId
 565                };
 66
 567                var response = await triggerInvoker.InvokeAsync(triggerRequest, cancellationToken);
 68
 569                if (response.CannotStart)
 70                {
 071                    logger.LogWarning("Workflow activation strategy disallowed starting workflow {WorkflowDefinitionHand
 072                    continue;
 73                }
 74
 575                responses.Add(response.ToRunWorkflowInstanceResponse());
 76            }
 577        }
 78
 579        return responses;
 580    }
 81
 82    private async Task<ICollection<RunWorkflowInstanceResponse>> ResumeExistingWorkflowsAsync(string stimulusHash, Stimu
 83    {
 684        var input = metadata?.Input;
 685        var properties = metadata?.Properties;
 86
 687        var bookmarkFilter = new BookmarkFilter
 688        {
 689            Hash = stimulusHash,
 690            CorrelationId = metadata?.CorrelationId,
 691            WorkflowInstanceId = metadata?.WorkflowInstanceId,
 692            ActivityInstanceId = metadata?.ActivityInstanceId,
 693            BookmarkId = metadata?.BookmarkId
 694        };
 695        var responses = (await workflowResumer.ResumeAsync(bookmarkFilter, new()
 696        {
 697            Input = input,
 698            Properties = properties
 699        }, cancellationToken)).ToList();
 100
 6101        if (responses.Count > 0)
 102        {
 2103            logger.LogDebug("Successfully resumed {WorkflowCount} workflow instances using stimulus {StimulusHash}", res
 2104            return responses;
 105        }
 106
 107        // If no bookmarks were matched, enqueue the request in case a matching bookmark is created in the near future.
 4108        var workflowInstanceId = metadata?.WorkflowInstanceId;
 109
 4110        var bookmarkQueueItem = new NewBookmarkQueueItem
 4111        {
 4112            WorkflowInstanceId = workflowInstanceId,
 4113            BookmarkId = metadata?.BookmarkId,
 4114            CorrelationId = metadata?.CorrelationId,
 4115            StimulusHash = stimulusHash,
 4116            Options = new()
 4117            {
 4118                Input = input,
 4119                Properties = properties
 4120            }
 4121        };
 122
 4123        logger.LogDebug("Bookmark queue item enqueued with stimulus: {StimulusHash}", bookmarkQueueItem.StimulusHash);
 124
 4125        await bookmarkQueue.EnqueueAsync(bookmarkQueueItem, cancellationToken);
 126
 4127        return responses;
 6128    }
 129}