using System.Text.Json;
using Elsa.Common.Models;
using Elsa.Extensions;
using Elsa.Scheduling.Activities;
using Elsa.Scheduling.Contracts;
using Elsa.Workflows.Core.Contracts;
using Elsa.Workflows.Core.Serialization;
using Elsa.Workflows.Runtime.Entities;
using Elsa.Workflows.Runtime.Models.Requests;
namespace Elsa.Scheduling.Services;
///
/// A default implementation of that schedules triggers using .
///
public class DefaultTriggerScheduler : ITriggerScheduler
{
private readonly IWorkflowScheduler _workflowScheduler;
private readonly IBookmarkPayloadSerializer _bookmarkPayloadSerializer;
///
/// Initializes a new instance of the class.
///
public DefaultTriggerScheduler(IWorkflowScheduler workflowScheduler, IBookmarkPayloadSerializer bookmarkPayloadSerializer)
{
_workflowScheduler = workflowScheduler;
_bookmarkPayloadSerializer = bookmarkPayloadSerializer;
}
///
public async Task ScheduleAsync(IEnumerable triggers, CancellationToken cancellationToken = default)
{
var triggerList = triggers.ToList();
// Select all Timer triggers.
var timerTriggers = triggerList.Filter().ToList();
var startAtTriggers = triggerList.Filter().ToList();
// Schedule each Timer trigger.
foreach (var trigger in timerTriggers)
{
var (startAt, interval) = _bookmarkPayloadSerializer.Deserialize(trigger.Data!);
var input = new { StartAt = startAt, Interval = interval }.ToDictionary();
var request = new DispatchWorkflowDefinitionRequest
{
DefinitionId = trigger.WorkflowDefinitionId,
VersionOptions = VersionOptions.Published,
TriggerActivityId = trigger.ActivityId,
Input = input
};
await _workflowScheduler.ScheduleRecurringAsync(trigger.Id, request, startAt, interval, cancellationToken);
}
// Schedule each StartAt trigger.
foreach (var trigger in startAtTriggers)
{
var executeAt = _bookmarkPayloadSerializer.Deserialize(trigger.Data!).ExecuteAt;
var input = new { ExecuteAt = executeAt }.ToDictionary();
var request = new DispatchWorkflowDefinitionRequest
{
DefinitionId = trigger.WorkflowDefinitionId,
VersionOptions = VersionOptions.Published,
TriggerActivityId = trigger.ActivityId,
Input = input
};
await _workflowScheduler.ScheduleAtAsync(trigger.Id, request, executeAt, cancellationToken);
}
}
///
public async Task UnscheduleAsync(IEnumerable triggers, CancellationToken cancellationToken = default)
{
var triggerList = triggers.ToList();
// Select all Timer triggers.
var timerTriggers = triggerList.Filter().ToList();
// Select all StartAt triggers.
var startAtTriggers = triggerList.Filter().ToList();
// Concatenate the filtered triggers.
var filteredTriggers = timerTriggers.Concat(startAtTriggers).ToList();
// Unschedule each trigger.
foreach (var trigger in filteredTriggers)
await _workflowScheduler.UnscheduleAsync(trigger.Id, cancellationToken);
}
}