using System.Runtime.CompilerServices; using Elsa.Common.Contracts; using Elsa.Extensions; using Elsa.Scheduling.Bookmarks; using Elsa.Workflows.Core; using Elsa.Workflows.Core.Attributes; using Elsa.Workflows.Core.Models; namespace Elsa.Scheduling.Activities; /// /// Represents a timer to periodically trigger the workflow. /// [Activity("Elsa", "Scheduling", "Trigger workflow execution at a specific interval.")] public class Timer : EventGenerator { /// public Timer([CallerFilePath] string? source = default, [CallerLineNumber] int? line = default) : base(source, line) { } /// public Timer(TimeSpan interval, [CallerFilePath] string? source = default, [CallerLineNumber] int? line = default) : this(new Input(interval), source, line) { } /// public Timer(Input interval, [CallerFilePath] string? source = default, [CallerLineNumber] int? line = default) : this(source, line) { Interval = interval; } /// /// The interval at which the timer should execute. /// [Input(Description = "The interval at which the timer should execute.", DefaultValue = "00:01:00")] public Input Interval { get; set; } = default!; /// protected override async ValueTask ExecuteAsync(ActivityExecutionContext context) { if(context.IsTriggerOfWorkflow()) { await context.CompleteActivityAsync(); return; } var clock = context.ExpressionExecutionContext.GetRequiredService(); var timeSpan = context.ExpressionExecutionContext.Get(Interval); var resumeAt = clock.UtcNow.Add(timeSpan); context.JournalData.Add("ResumeAt", resumeAt); context.CreateBookmark(new TimerBookmarkPayload(resumeAt)); } /// protected override object GetTriggerPayload(TriggerIndexingContext context) { var interval = context.ExpressionExecutionContext.Get(Interval); var clock = context.ExpressionExecutionContext.GetRequiredService(); var executeAt = clock.UtcNow.Add(interval); return new TimerTriggerPayload(executeAt, interval); } /// /// Creates a new activity set to trigger at the specified interval. /// public static Timer FromTimeSpan(TimeSpan value, [CallerFilePath] string? source = default, [CallerLineNumber] int? line = default) => new(value, source, line); /// /// Creates a new activity set to trigger at the specified interval in seconds. /// public static Timer FromSeconds(double value, [CallerFilePath] string? source = default, [CallerLineNumber] int? line = default) => FromTimeSpan(TimeSpan.FromSeconds(value), source, line); }