< Summary

Information
Class: Elsa.Workflows.Runtime.WorkflowHost
Assembly: Elsa.Workflows.Runtime
File(s): /home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Workflows.Runtime/Services/WorkflowHost.cs
Line coverage
0%
Covered lines: 0
Uncovered lines: 66
Coverable lines: 66
Total lines: 134
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 24
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%210%
get_WorkflowGraph()100%210%
get_Workflow()100%210%
get_WorkflowState()100%210%
get_LastResult()100%210%
CanStartWorkflowAsync()0%4260%
RunWorkflowAsync()0%272160%
CancelWorkflowAsync()0%620%
PersistStateAsync()100%210%
PersistStateAsync()100%210%

File(s)

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

#LineLine coverage
 1using Elsa.Workflows.Activities;
 2using Elsa.Workflows.Management;
 3using Elsa.Workflows.Models;
 4using Elsa.Workflows.Options;
 5using Elsa.Workflows.State;
 6using Microsoft.Extensions.DependencyInjection;
 7using Microsoft.Extensions.Logging;
 8
 9namespace Elsa.Workflows.Runtime;
 10
 11/// <summary>
 12/// Represents a host of a workflow instance to interact with.
 13/// </summary>
 14[Obsolete("Use IWorkflowRuntime and IWorkflowClient services instead.")]
 15public class WorkflowHost : IWorkflowHost
 16{
 17    private readonly IServiceScopeFactory _serviceScopeFactory;
 18    private readonly ILogger<WorkflowHost> _logger;
 19    private CancellationTokenSource? _linkedTokenSource;
 20
 21    /// <summary>
 22    /// Initializes a new instance of the <see cref="WorkflowHost"/> class.
 23    /// </summary>
 024    public WorkflowHost(
 025        IServiceScopeFactory serviceScopeFactory,
 026        WorkflowGraph workflowGraph,
 027        WorkflowState workflowState,
 028        ILogger<WorkflowHost> logger)
 29    {
 030        WorkflowGraph = workflowGraph;
 031        WorkflowState = workflowState;
 032        _serviceScopeFactory = serviceScopeFactory;
 033        _logger = logger;
 034    }
 35
 36    /// <inheritdoc />
 037    public WorkflowGraph WorkflowGraph { get; }
 38
 39    /// <inheritdoc />
 040    public Workflow Workflow => WorkflowGraph.Workflow;
 41
 42    /// <inheritdoc />
 043    public WorkflowState WorkflowState { get; set; }
 44
 45    /// <inheritdoc />
 046    public object? LastResult { get; set; }
 47
 48    /// <inheritdoc />
 49    public async Task<bool> CanStartWorkflowAsync(RunWorkflowOptions? @params = default, CancellationToken cancellationT
 50    {
 051        var strategyType = Workflow.Options.ActivationStrategyType;
 52
 053        if (strategyType == null)
 054            return true;
 55
 056        await using var scope = _serviceScopeFactory.CreateAsyncScope();
 057        var instantiationStrategies = scope.ServiceProvider.GetServices<IWorkflowActivationStrategy>();
 058        var strategy = instantiationStrategies.FirstOrDefault(x => x.GetType() == strategyType);
 59
 060        if (strategy == null)
 061            return true;
 62
 063        var correlationId = @params?.CorrelationId;
 064        var strategyContext = new WorkflowInstantiationStrategyContext(Workflow, correlationId, cancellationToken);
 065        return await strategy.GetAllowActivationAsync(strategyContext);
 066    }
 67
 68    /// <inheritdoc />
 69    public async Task<RunWorkflowResult> RunWorkflowAsync(RunWorkflowOptions? @params = null, CancellationToken cancella
 70    {
 071        if (WorkflowState.Status != WorkflowStatus.Running)
 72        {
 073            _logger.LogWarning("Attempt to resume workflow {WorkflowInstanceId} that is not in the Running state. The ac
 074            return new(null!, WorkflowState, Workflow, null, Journal.Empty);
 75        }
 76
 077        var runOptions = new RunWorkflowOptions
 078        {
 079            WorkflowInstanceId = WorkflowState.Id,
 080            CorrelationId = @params?.CorrelationId,
 081            Input = @params?.Input,
 082            Properties = @params?.Properties,
 083            ActivityHandle = @params?.ActivityHandle,
 084            BookmarkId = @params?.BookmarkId,
 085            TriggerActivityId = @params?.TriggerActivityId,
 086            ParentWorkflowInstanceId = @params?.ParentWorkflowInstanceId
 087        };
 088        _linkedTokenSource = new();
 089        var linkedCancellationToken = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, _linkedTokenSou
 90
 091        await using var scope = _serviceScopeFactory.CreateAsyncScope();
 092        var workflowRunner = scope.ServiceProvider.GetRequiredService<IWorkflowRunner>();
 093        var workflowResult = await workflowRunner.RunAsync(WorkflowGraph, WorkflowState, runOptions, linkedCancellationT
 94
 095        WorkflowState = workflowResult.WorkflowState;
 096        await PersistStateAsync(scope, cancellationToken);
 97
 098        _linkedTokenSource.Dispose();
 099        _linkedTokenSource = null;
 100
 0101        return workflowResult;
 0102    }
 103
 104    /// <inheritdoc />
 105    public async Task CancelWorkflowAsync(CancellationToken cancellationToken = default)
 106    {
 107        // If the workflow is currently executing, cancel it. This will cause the workflow to be cancelled gracefully.
 0108        if (_linkedTokenSource != null)
 109        {
 0110            _linkedTokenSource.Cancel();
 0111            return;
 112        }
 113
 114        // Otherwise, cancel the workflow by executing the canceler. This will set up a workflow execution pipeline that
 0115        await using var scope = _serviceScopeFactory.CreateAsyncScope();
 0116        var serviceProvider = scope.ServiceProvider;
 0117        var workflowCanceler = serviceProvider.GetRequiredService<IWorkflowCanceler>();
 0118        WorkflowState = await workflowCanceler.CancelWorkflowAsync(WorkflowGraph, WorkflowState, cancellationToken);
 0119        await PersistStateAsync(scope, cancellationToken);
 0120    }
 121
 122    /// <inheritdoc />
 123    public async Task PersistStateAsync(CancellationToken cancellationToken = default)
 124    {
 0125        await using var scope = _serviceScopeFactory.CreateAsyncScope();
 0126        await PersistStateAsync(scope, cancellationToken);
 0127    }
 128
 129    private async Task PersistStateAsync(IServiceScope scope, CancellationToken cancellationToken = default)
 130    {
 0131        var workflowInstanceManager = scope.ServiceProvider.GetRequiredService<IWorkflowInstanceManager>();
 0132        await workflowInstanceManager.SaveAsync(WorkflowState, cancellationToken);
 0133    }
 134}