Fix TimerEvent and CronEvent
This commit is contained in:
parent
4474d9cdc2
commit
0b81bba3d4
|
|
@ -2,6 +2,8 @@ using Elsa.ActivityResults;
|
|||
using Elsa.Attributes;
|
||||
using Elsa.Services;
|
||||
using Elsa.Services.Models;
|
||||
using NCrontab;
|
||||
using NodaTime;
|
||||
|
||||
// ReSharper disable once CheckNamespace
|
||||
namespace Elsa.Activities.Timers
|
||||
|
|
@ -13,10 +15,39 @@ namespace Elsa.Activities.Timers
|
|||
)]
|
||||
public class CronEvent : Activity
|
||||
{
|
||||
private readonly IClock _clock;
|
||||
|
||||
public CronEvent(IClock clock)
|
||||
{
|
||||
_clock = clock;
|
||||
}
|
||||
|
||||
|
||||
[ActivityProperty(Hint = "Specify a CRON expression. See https://crontab.guru/ for help.")]
|
||||
public string CronExpression { get; set; } = "* * * * *";
|
||||
|
||||
public Instant ExecuteAt
|
||||
{
|
||||
get => GetState<Instant>();
|
||||
set => SetState(value);
|
||||
}
|
||||
|
||||
protected override IActivityExecutionResult OnExecute(ActivityExecutionContext context)
|
||||
{
|
||||
if (context.WorkflowExecutionContext.IsFirstPass)
|
||||
return Done();
|
||||
|
||||
ExecuteAt = GetNextOccurrence(CronExpression);
|
||||
return Suspend();
|
||||
}
|
||||
|
||||
protected override IActivityExecutionResult OnExecute(ActivityExecutionContext context) => context.WorkflowExecutionContext.IsFirstPass ? (IActivityExecutionResult) Done() : Suspend();
|
||||
protected override IActivityExecutionResult OnResume() => Done();
|
||||
|
||||
private Instant GetNextOccurrence(string cronExpression)
|
||||
{
|
||||
var schedule = CrontabSchedule.Parse(cronExpression);
|
||||
var now = _clock.GetCurrentInstant();
|
||||
return Instant.FromDateTimeUtc(schedule.GetNextOccurrence(now.ToDateTimeUtc()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -10,10 +10,31 @@ namespace Elsa.Activities.Timers
|
|||
[Trigger(Category = "Timers", Description = "Triggers at a specified interval.")]
|
||||
public class TimerEvent : Activity
|
||||
{
|
||||
private readonly IClock _clock;
|
||||
|
||||
public TimerEvent(IClock clock)
|
||||
{
|
||||
_clock = clock;
|
||||
}
|
||||
|
||||
[ActivityProperty(Hint = "An expression that evaluates to a Duration value.")]
|
||||
public Duration Timeout { get; set; } = default!;
|
||||
|
||||
protected override IActivityExecutionResult OnExecute(ActivityExecutionContext context) => context.WorkflowExecutionContext.IsFirstPass ? (IActivityExecutionResult)Done() : Suspend();
|
||||
public Instant ExecuteAt
|
||||
{
|
||||
get => GetState<Instant>();
|
||||
set => SetState(value);
|
||||
}
|
||||
|
||||
protected override IActivityExecutionResult OnExecute(ActivityExecutionContext context)
|
||||
{
|
||||
if (context.WorkflowExecutionContext.IsFirstPass)
|
||||
return Done();
|
||||
|
||||
ExecuteAt = _clock.GetCurrentInstant().Plus(Timeout);
|
||||
return Suspend();
|
||||
}
|
||||
|
||||
protected override IActivityExecutionResult OnResume() => Done();
|
||||
}
|
||||
}
|
||||
|
|
@ -13,29 +13,14 @@ namespace Elsa.Activities.Timers.Triggers
|
|||
|
||||
public class CronEventTriggerProvider : TriggerProvider<CronEventTrigger, CronEvent>
|
||||
{
|
||||
private readonly IClock _clock;
|
||||
|
||||
public CronEventTriggerProvider(IClock clock)
|
||||
{
|
||||
_clock = clock;
|
||||
}
|
||||
|
||||
public override async ValueTask<ITrigger> GetTriggerAsync(TriggerProviderContext<CronEvent> context, CancellationToken cancellationToken)
|
||||
{
|
||||
var cron = await context.GetActivity<CronEvent>().GetPropertyValueAsync(x => x.CronExpression, cancellationToken);
|
||||
var executeAt = GetNextOccurrence(cron);
|
||||
var executeAt = context.GetActivity<CronEvent>().GetState(x => x.ExecuteAt);
|
||||
|
||||
return new TimerEventTrigger
|
||||
{
|
||||
ExecuteAt = executeAt
|
||||
};
|
||||
}
|
||||
|
||||
private Instant GetNextOccurrence(string cronExpression)
|
||||
{
|
||||
var schedule = CrontabSchedule.Parse(cronExpression);
|
||||
var now = _clock.GetCurrentInstant();
|
||||
return Instant.FromDateTimeUtc(schedule.GetNextOccurrence(now.ToDateTimeUtc()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,4 @@
|
|||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Elsa.Triggers;
|
||||
using Elsa.Triggers;
|
||||
using NodaTime;
|
||||
|
||||
namespace Elsa.Activities.Timers.Triggers
|
||||
|
|
@ -12,18 +10,9 @@ namespace Elsa.Activities.Timers.Triggers
|
|||
|
||||
public class TimerEventTriggerProvider : TriggerProvider<TimerEventTrigger, TimerEvent>
|
||||
{
|
||||
private readonly IClock _clock;
|
||||
|
||||
public TimerEventTriggerProvider(IClock clock)
|
||||
public override ITrigger GetTrigger(TriggerProviderContext<TimerEvent> context)
|
||||
{
|
||||
_clock = clock;
|
||||
}
|
||||
|
||||
public override async ValueTask<ITrigger> GetTriggerAsync(TriggerProviderContext<TimerEvent> context, CancellationToken cancellationToken)
|
||||
{
|
||||
var duration = await context.GetActivity<TimerEvent>().GetPropertyValueAsync(x => x.Timeout, cancellationToken);
|
||||
var now = _clock.GetCurrentInstant();
|
||||
var executeAt = now.Plus(duration);
|
||||
var executeAt = context.GetActivity<TimerEvent>().GetState(x => x.ExecuteAt);
|
||||
|
||||
return new TimerEventTrigger
|
||||
{
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ namespace Elsa
|
|||
return (T)value!;
|
||||
}
|
||||
|
||||
public static T GetActivityState<TActivity, T>(
|
||||
public static T? GetActivityState<TActivity, T>(
|
||||
this IWorkflowBlueprint workflowBlueprint,
|
||||
Expression<Func<TActivity, T>> propertyExpression,
|
||||
ActivityExecutionContext activityExecutionContext) where TActivity : IActivity
|
||||
|
|
@ -51,13 +51,14 @@ namespace Elsa
|
|||
return GetActivityState<T>(propertyName, activityExecutionContext);
|
||||
}
|
||||
|
||||
public static T GetActivityState<T>(
|
||||
public static T? GetActivityState<T>(
|
||||
string propertyName,
|
||||
ActivityExecutionContext activityExecutionContext)
|
||||
{
|
||||
var activity = activityExecutionContext.ActivityInstance;
|
||||
var serializer = activityExecutionContext.GetService<JsonSerializer>();
|
||||
return activity.Data[propertyName]!.ToObject<T>(serializer)!;
|
||||
var value = activity.Data[propertyName];
|
||||
return value != null ? value.ToObject<T>(serializer) : default;
|
||||
}
|
||||
|
||||
public static IEnumerable<IWorkflowBlueprint> WithVersion(
|
||||
|
|
|
|||
Loading…
Reference in a new issue