using Elsa.Common; using Elsa.Common.Multitenancy; using Elsa.Common.Models; using Elsa.Scheduling.Options; using Elsa.Workflows.Runtime; using Elsa.Workflows.Runtime.Filters; using Elsa.Workflows.Runtime.Tasks; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; namespace Elsa.Scheduling.StartupTasks; /// /// Enqueues schedule creation when using the default scheduler, which doesn't have its own persistence layer like Quartz or Hangfire. /// [TaskDependency(typeof(PopulateRegistriesStartupTask))] public class CreateSchedulesStartupTask(IServiceProvider serviceProvider, IOptions options) : IStartupTask { public async Task ExecuteAsync(CancellationToken cancellationToken) { var workQueue = serviceProvider.GetService(); if (workQueue != null) await workQueue.EnqueueAsync(CreateSchedulesAsync, cancellationToken); else await CreateSchedulesAsync(serviceProvider, cancellationToken); } private async Task CreateSchedulesAsync(IServiceProvider serviceProvider, CancellationToken cancellationToken) { var triggerStore = serviceProvider.GetRequiredService(); var bookmarkStore = serviceProvider.GetRequiredService(); var triggerScheduler = serviceProvider.GetRequiredService(); var bookmarkScheduler = serviceProvider.GetRequiredService(); var pageSize = Math.Max(1, options.Value.StartupSchedulePageSize); var stimulusNames = new[] { SchedulingStimulusNames.Cron, SchedulingStimulusNames.Timer, SchedulingStimulusNames.StartAt, SchedulingStimulusNames.Delay, }; var triggerFilter = new TriggerFilter { Names = stimulusNames }; var bookmarkFilter = new BookmarkFilter { Names = stimulusNames }; await ScheduleTriggersAsync(triggerStore, triggerScheduler, triggerFilter, pageSize, cancellationToken); await ScheduleBookmarksAsync(bookmarkStore, bookmarkScheduler, bookmarkFilter, pageSize, cancellationToken); } private static async Task ScheduleTriggersAsync(ITriggerStore triggerStore, ITriggerScheduler triggerScheduler, TriggerFilter triggerFilter, int pageSize, CancellationToken cancellationToken) { var pageArgs = PageArgs.FromRange(0, pageSize); while (true) { var page = await triggerStore.FindManyAsync(triggerFilter, pageArgs, cancellationToken); if (page.Items.Count == 0) break; await triggerScheduler.ScheduleAsync(page.Items, cancellationToken); var nextOffset = pageArgs.Offset.GetValueOrDefault() + page.Items.Count; if (nextOffset >= page.TotalCount) break; pageArgs = pageArgs.Next(); } } private static async Task ScheduleBookmarksAsync(IBookmarkStore bookmarkStore, IBookmarkScheduler bookmarkScheduler, BookmarkFilter bookmarkFilter, int pageSize, CancellationToken cancellationToken) { var pageArgs = PageArgs.FromRange(0, pageSize); while (true) { var page = await bookmarkStore.FindManyAsync(bookmarkFilter, pageArgs, cancellationToken); if (page.Items.Count == 0) break; await bookmarkScheduler.ScheduleAsync(page.Items, cancellationToken); var nextOffset = pageArgs.Offset.GetValueOrDefault() + page.Items.Count; if (nextOffset >= page.TotalCount) break; pageArgs = pageArgs.Next(); } } }