< Summary

Information
Class: Elsa.Workflows.Runtime.Services.InterruptedRecoveryScanner
Assembly: Elsa.Workflows.Runtime
File(s): /home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Workflows.Runtime/Services/InterruptedRecoveryScanner.cs
Line coverage
100%
Covered lines: 35
Uncovered lines: 0
Coverable lines: 35
Total lines: 78
Line coverage: 100%
Branch coverage
92%
Covered branches: 13
Total branches: 14
Branch coverage: 92.8%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
ScanAndRequeueAsync()92.85%1414100%

File(s)

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

#LineLine coverage
 1using Elsa.Common;
 2using Elsa.Common.Multitenancy;
 3using Elsa.Workflows.Management;
 4using Elsa.Workflows.Management.Filters;
 5using Elsa.Workflows.Runtime.Options;
 6using Microsoft.Extensions.Logging;
 7using Microsoft.Extensions.Options;
 8
 9namespace Elsa.Workflows.Runtime.Services;
 10
 11/// <summary>
 12/// Default implementation of <see cref="IInterruptedRecoveryScanner"/>.
 13/// </summary>
 14public sealed class InterruptedRecoveryScanner : IInterruptedRecoveryScanner
 15{
 16    private readonly IWorkflowRestarter _restarter;
 17    private readonly IWorkflowInstanceStore _instanceStore;
 18    private readonly IOptions<RuntimeOptions> _runtimeOptions;
 19    private readonly ILogger<InterruptedRecoveryScanner> _logger;
 20    private readonly ITenantService? _tenantService;
 21    private readonly ITenantAccessor? _tenantAccessor;
 22
 9223    public InterruptedRecoveryScanner(
 9224        IWorkflowRestarter restarter,
 9225        IWorkflowInstanceStore instanceStore,
 9226        IOptions<RuntimeOptions> runtimeOptions,
 9227        ILogger<InterruptedRecoveryScanner> logger,
 9228        ITenantService? tenantService = null,
 9229        ITenantAccessor? tenantAccessor = null)
 30    {
 9231        _restarter = restarter;
 9232        _instanceStore = instanceStore;
 9233        _runtimeOptions = runtimeOptions;
 9234        _logger = logger;
 9235        _tenantService = tenantService;
 9236        _tenantAccessor = tenantAccessor;
 9237    }
 38
 39    /// <inheritdoc />
 40    public async ValueTask<int> ScanAndRequeueAsync(CancellationToken cancellationToken)
 41    {
 9242        var filter = new WorkflowInstanceFilter { WorkflowSubStatus = WorkflowSubStatus.Interrupted };
 9243        var batchSize = _runtimeOptions.Value.RestartInterruptedWorkflowsBatchSize;
 9244        var instances = _instanceStore.EnumerateSummariesAsync(filter, batchSize, cancellationToken);
 9245        var requeued = 0;
 46
 9247        _logger.LogInformation("Scanning for workflows interrupted by graceful drain.");
 48
 43849        await foreach (var summary in instances.WithCancellation(cancellationToken))
 50        {
 51            try
 52            {
 12753                var tenantId = summary.TenantId ?? string.Empty;
 54
 12755                if (_tenantService is not null && _tenantAccessor is not null && !string.IsNullOrWhiteSpace(tenantId) &&
 56                {
 157                    var tenant = await _tenantService.FindAsync(tenantId, cancellationToken) ?? new Tenant { Id = tenant
 58
 159                    using (_tenantAccessor.PushContext(tenant))
 160                        await _restarter.RestartWorkflowAsync(summary.Id, cancellationToken);
 61                }
 62                else
 63                {
 12664                    await _restarter.RestartWorkflowAsync(summary.Id, cancellationToken);
 65                }
 66
 12667                requeued++;
 12668            }
 169            catch (Exception ex) when (!ex.IsFatal())
 70            {
 171                _logger.LogError(ex, "Failed to requeue interrupted workflow {WorkflowInstanceId}; will be retried by th
 172            }
 12773        }
 74
 9275        _logger.LogInformation("Interrupted-workflow scan complete; requeued {Count} instance(s).", requeued);
 9276        return requeued;
 9277    }
 78}