Skip to content

Commit 0dc268f

Browse files
authored
Fix: Duration-based scheduling is properly formed (#1462)
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 <[email protected]>
1 parent e9ee4d2 commit 0dc268f

File tree

4 files changed

+18
-14
lines changed

4 files changed

+18
-14
lines changed

src/Dapr.Jobs/DaprJobsGrpcClient.cs

+3-2
Original file line numberDiff line numberDiff line change
@@ -84,11 +84,12 @@ public override async Task ScheduleJobAsync(string jobName, DaprJobSchedule sche
8484
{
8585
job.DueTime = schedule.ExpressionValue;
8686
}
87-
else if (schedule.IsCronExpression || schedule.IsDurationExpression || schedule.IsPrefixedPeriodExpression)
87+
else if (schedule.IsCronExpression || schedule.IsPrefixedPeriodExpression || schedule.IsDurationExpression)
8888
{
8989
job.Schedule = schedule.ExpressionValue;
9090
}
91-
else if (startingFrom is not null)
91+
92+
if (startingFrom is not null)
9293
{
9394
job.DueTime = ((DateTimeOffset)startingFrom).ToString("O");
9495
}

src/Dapr.Jobs/Extensions/TimeSpanExtensions.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ public static string ToDurationString(this TimeSpan timespan)
6767
/// <returns>True if the string represents a parseable interval duration; false if not.</returns>
6868
public static bool IsDurationString(this string interval)
6969
{
70-
interval = interval.Replace("ms", "q");
70+
interval = interval.Replace("ms", "q").Replace("@every ", string.Empty);
7171
return hourRegex.Match(interval).Success ||
7272
minuteRegex.Match(interval).Success ||
7373
secondRegex.Match(interval).Success ||

src/Dapr.Jobs/Models/DaprJobSchedule.cs

+3-9
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,8 @@ public static DaprJobSchedule FromCronExpression(CronExpressionBuilder builder)
6565
/// </summary>
6666
/// <param name="scheduledTime">The date and time when the job should be triggered.</param>
6767
/// <returns></returns>
68-
public static DaprJobSchedule FromDateTime(DateTimeOffset scheduledTime)
69-
{
70-
return new DaprJobSchedule(scheduledTime.ToString("O"));
71-
}
72-
68+
public static DaprJobSchedule FromDateTime(DateTimeOffset scheduledTime) => new(scheduledTime.ToString("O"));
69+
7370
/// <summary>
7471
/// Specifies a schedule using a Cron-like expression or '@' prefixed period strings.
7572
/// </summary>
@@ -86,10 +83,7 @@ public static DaprJobSchedule FromExpression(string expression)
8683
/// Specifies a schedule using a duration interval articulated via a <see cref="TimeSpan"/>.
8784
/// </summary>
8885
/// <param name="duration">The duration interval.</param>
89-
public static DaprJobSchedule FromDuration(TimeSpan duration)
90-
{
91-
return new DaprJobSchedule(duration.ToDurationString());
92-
}
86+
public static DaprJobSchedule FromDuration(TimeSpan duration) => new($"@every {duration.ToDurationString()}");
9387

9488
/// <summary>
9589
/// Specifies a schedule in which the job is triggered to run once a year.

test/Dapr.Jobs.Test/Models/DaprJobScheduleTests.cs

+11-2
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,16 @@ public sealed class DaprJobScheduleTests
2323
public void FromDuration_Validate()
2424
{
2525
var schedule = DaprJobSchedule.FromDuration(new TimeSpan(12, 8, 16));
26-
Assert.Equal("12h8m16s", schedule.ExpressionValue);
26+
Assert.Equal("@every 12h8m16s", schedule.ExpressionValue);
27+
}
28+
29+
[Fact]
30+
public void FromExpression_Duration()
31+
{
32+
var every5Seconds = new TimeSpan(0, 0, 0, 5);
33+
var schedule = DaprJobSchedule.FromDuration(every5Seconds);
34+
35+
Assert.Equal("@every 5s", schedule.ExpressionValue);
2736
}
2837

2938
[Fact]
@@ -108,7 +117,7 @@ public void IsDurationExpression()
108117
Assert.True(schedule.IsDurationExpression);
109118
Assert.False(schedule.IsPointInTimeExpression);
110119
Assert.False(schedule.IsCronExpression);
111-
Assert.False(schedule.IsPrefixedPeriodExpression);
120+
Assert.True(schedule.IsPrefixedPeriodExpression); //A duration expression _is_ a prefixed period with @every
112121
}
113122

114123
[Fact]

0 commit comments

Comments
 (0)