Skip to content

Commit

Permalink
Fix: Duration-based scheduling is properly formed (#1462)
Browse files Browse the repository at this point in the history
Fixed: Duration-based scheduling should be properly formatted

When using a duration-based schedule value (e.g. "5s", it's important that the value be preceded by "@every " so it's properly evaluated by the runtime. While a value of "5s" is perfectly valid in the `dueTime` property, the scheduler expects either a Cron expression or a prefixed duration value, necessitating this change.

---------

Signed-off-by: Whit Waldo <whit.waldo@innovian.net>
  • Loading branch information
WhitWaldo authored Feb 20, 2025
1 parent e9ee4d2 commit 0dc268f
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 14 deletions.
5 changes: 3 additions & 2 deletions src/Dapr.Jobs/DaprJobsGrpcClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,12 @@ public override async Task ScheduleJobAsync(string jobName, DaprJobSchedule sche
{
job.DueTime = schedule.ExpressionValue;
}
else if (schedule.IsCronExpression || schedule.IsDurationExpression || schedule.IsPrefixedPeriodExpression)
else if (schedule.IsCronExpression || schedule.IsPrefixedPeriodExpression || schedule.IsDurationExpression)
{
job.Schedule = schedule.ExpressionValue;
}
else if (startingFrom is not null)

if (startingFrom is not null)
{
job.DueTime = ((DateTimeOffset)startingFrom).ToString("O");
}
Expand Down
2 changes: 1 addition & 1 deletion src/Dapr.Jobs/Extensions/TimeSpanExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ public static string ToDurationString(this TimeSpan timespan)
/// <returns>True if the string represents a parseable interval duration; false if not.</returns>
public static bool IsDurationString(this string interval)
{
interval = interval.Replace("ms", "q");
interval = interval.Replace("ms", "q").Replace("@every ", string.Empty);
return hourRegex.Match(interval).Success ||
minuteRegex.Match(interval).Success ||
secondRegex.Match(interval).Success ||
Expand Down
12 changes: 3 additions & 9 deletions src/Dapr.Jobs/Models/DaprJobSchedule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,8 @@ public static DaprJobSchedule FromCronExpression(CronExpressionBuilder builder)
/// </summary>
/// <param name="scheduledTime">The date and time when the job should be triggered.</param>
/// <returns></returns>
public static DaprJobSchedule FromDateTime(DateTimeOffset scheduledTime)
{
return new DaprJobSchedule(scheduledTime.ToString("O"));
}

public static DaprJobSchedule FromDateTime(DateTimeOffset scheduledTime) => new(scheduledTime.ToString("O"));

/// <summary>
/// Specifies a schedule using a Cron-like expression or '@' prefixed period strings.
/// </summary>
Expand All @@ -86,10 +83,7 @@ public static DaprJobSchedule FromExpression(string expression)
/// Specifies a schedule using a duration interval articulated via a <see cref="TimeSpan"/>.
/// </summary>
/// <param name="duration">The duration interval.</param>
public static DaprJobSchedule FromDuration(TimeSpan duration)
{
return new DaprJobSchedule(duration.ToDurationString());
}
public static DaprJobSchedule FromDuration(TimeSpan duration) => new($"@every {duration.ToDurationString()}");

/// <summary>
/// Specifies a schedule in which the job is triggered to run once a year.
Expand Down
13 changes: 11 additions & 2 deletions test/Dapr.Jobs.Test/Models/DaprJobScheduleTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,16 @@ public sealed class DaprJobScheduleTests
public void FromDuration_Validate()
{
var schedule = DaprJobSchedule.FromDuration(new TimeSpan(12, 8, 16));
Assert.Equal("12h8m16s", schedule.ExpressionValue);
Assert.Equal("@every 12h8m16s", schedule.ExpressionValue);
}

[Fact]
public void FromExpression_Duration()
{
var every5Seconds = new TimeSpan(0, 0, 0, 5);
var schedule = DaprJobSchedule.FromDuration(every5Seconds);

Assert.Equal("@every 5s", schedule.ExpressionValue);
}

[Fact]
Expand Down Expand Up @@ -108,7 +117,7 @@ public void IsDurationExpression()
Assert.True(schedule.IsDurationExpression);
Assert.False(schedule.IsPointInTimeExpression);
Assert.False(schedule.IsCronExpression);
Assert.False(schedule.IsPrefixedPeriodExpression);
Assert.True(schedule.IsPrefixedPeriodExpression); //A duration expression _is_ a prefixed period with @every
}

[Fact]
Expand Down

0 comments on commit 0dc268f

Please sign in to comment.