< Summary

Information
Class: Elsa.Scheduling.Services.DefaultTriggerScheduler
Assembly: Elsa.Scheduling
File(s): /home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Scheduling/Services/DefaultTriggerScheduler.cs
Line coverage
68%
Covered lines: 41
Uncovered lines: 19
Coverable lines: 60
Total lines: 111
Line coverage: 68.3%
Branch coverage
64%
Covered branches: 9
Total branches: 14
Branch coverage: 64.2%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
ScheduleAsync()58.33%191262.74%
UnscheduleAsync()100%22100%

File(s)

/home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Scheduling/Services/DefaultTriggerScheduler.cs

#LineLine coverage
 1using Elsa.Common;
 2using Elsa.Extensions;
 3using Elsa.Scheduling.Activities;
 4using Elsa.Scheduling.Bookmarks;
 5using Elsa.Workflows.Models;
 6using Elsa.Workflows.Runtime.Entities;
 7using Microsoft.Extensions.Logging;
 8
 9namespace Elsa.Scheduling.Services;
 10
 11/// <summary>
 12/// A default implementation of <see cref="ITriggerScheduler"/> that schedules triggers using <see cref="IWorkflowSchedu
 13/// </summary>
 62214public class DefaultTriggerScheduler(IWorkflowScheduler workflowScheduler, ISystemClock systemClock, ILogger<DefaultTrig
 15    : ITriggerScheduler
 16{
 17    /// <inheritdoc />
 18    public async Task ScheduleAsync(IEnumerable<StoredTrigger> triggers, CancellationToken cancellationToken = default)
 19    {
 161820        var triggerList = triggers.ToList();
 161821        var timerTriggers = triggerList.Filter<Activities.Timer>();
 161822        var startAtTriggers = triggerList.Filter<StartAt>();
 161823        var cronTriggers = triggerList.Filter<Cron>();
 161824        var now = systemClock.UtcNow;
 25
 26        // Schedule each Timer trigger.
 324027        foreach (var trigger in timerTriggers)
 28        {
 229            var (startAt, interval) = trigger.GetPayload<TimerTriggerPayload>();
 230            var input = new { StartAt = startAt, Interval = interval }.ToDictionary();
 231            var request = new ScheduleNewWorkflowInstanceRequest
 232            {
 233                WorkflowDefinitionHandle = WorkflowDefinitionHandle.ByDefinitionVersionId(trigger.WorkflowDefinitionVers
 234                TriggerActivityId = trigger.ActivityId,
 235                Input = input
 236            };
 237            await workflowScheduler.ScheduleRecurringAsync(trigger.Id, request, startAt, interval, cancellationToken);
 38        }
 39
 40        // Schedule each StartAt trigger.
 323641        foreach (var trigger in startAtTriggers)
 42        {
 043            var executeAt = trigger.GetPayload<StartAtPayload>().ExecuteAt;
 44
 45            // If the trigger is in the past, log info and skip scheduling.
 046            if (executeAt < now)
 47            {
 048                logger.LogInformation("StartAt trigger is in the past. TriggerId: {TriggerId}. ExecuteAt: {ExecuteAt}. S
 049                continue;
 50            }
 51
 052            var input = new { ExecuteAt = executeAt }.ToDictionary();
 053            var request = new ScheduleNewWorkflowInstanceRequest
 054            {
 055                WorkflowDefinitionHandle = WorkflowDefinitionHandle.ByDefinitionVersionId(trigger.WorkflowDefinitionVers
 056                TriggerActivityId = trigger.ActivityId,
 057                Input = input
 058            };
 59
 060            await workflowScheduler.ScheduleAtAsync(trigger.Id, request, executeAt, cancellationToken);
 61        }
 62
 63        // Schedule each Cron trigger.
 323864        foreach (var trigger in cronTriggers)
 65        {
 166            var payload = trigger.GetPayload<CronTriggerPayload>();
 167            if(payload is null)
 68            {
 069                logger.LogWarning("Cron expression payload is empty. TriggerId: {TriggerId}. Skipping scheduling of this
 070                continue;
 71            }
 72
 173            var cronExpression = payload.CronExpression;
 74
 175            if (string.IsNullOrWhiteSpace(cronExpression))
 76            {
 077                logger.LogWarning("Cron expression is empty. TriggerId: {TriggerId}. Skipping scheduling of this trigger
 078                continue;
 79            }
 80
 181            var input = new { CronExpression = cronExpression }.ToDictionary();
 182            var request = new ScheduleNewWorkflowInstanceRequest
 183            {
 184                WorkflowDefinitionHandle = WorkflowDefinitionHandle.ByDefinitionVersionId(trigger.WorkflowDefinitionVers
 185                TriggerActivityId = trigger.ActivityId,
 186                Input = input
 187            };
 88            try
 89            {
 190                await workflowScheduler.ScheduleCronAsync(trigger.Id, request, cronExpression, cancellationToken);
 191            }
 092            catch (FormatException ex)
 93            {
 094                logger.LogWarning(ex, "Cron expression format error. CronExpression: {CronExpression}", cronExpression);
 095            }
 196        }
 161897    }
 98
 99    /// <inheritdoc />
 100    public async Task UnscheduleAsync(IEnumerable<StoredTrigger> triggers, CancellationToken cancellationToken = default
 101    {
 1482102        var triggerList = triggers.ToList();
 1482103        var timerTriggers = triggerList.Filter<Activities.Timer>();
 1482104        var startAtTriggers = triggerList.Filter<StartAt>();
 1482105        var cronTriggers = triggerList.Filter<Cron>();
 1482106        var filteredTriggers = timerTriggers.Concat(startAtTriggers).Concat(cronTriggers);
 107
 2966108        foreach (var trigger in filteredTriggers)
 1109            await workflowScheduler.UnscheduleAsync(trigger.Id, cancellationToken);
 1482110    }
 111}