Version v1.0 · dotnet
Recurring Jobs
Runtime recurring schedule administration operations.
Recurring Jobs
Use recurring attributes for schedule definition and IDurableScheduleAdminService for runtime schedule operations.
Define a recurring job
using DurableStack.Core.Abstractions;
using DurableStack.Hosting.DependencyInjection;
[DurableJob(Name = "daily-reconciliation", MaxAttempts = 4)]
[RecurringJob("0 2 * * *", TimeZone = "UTC", Enabled = true, AllowConcurrentRuns = false)]
public sealed class DailyReconciliationJob : IDurableJob
{
public Task ExecuteAsync(JobContext context, CancellationToken cancellationToken = default)
=> Task.CompletedTask;
}
Supported operations
- list all schedules (
includeDisabledoptional) - disable or enable by schedule name
- run schedule now (ad-hoc enqueue)
- update cron expression and time zone
Service usage
var scheduledJobs = await scheduleAdmin.ListScheduledJobsAsync(includeDisabled: true, cancellationToken);
var disabled = await scheduleAdmin.SetScheduledJobEnabledAsync(
jobName: "heartbeat-every-minute",
enabled: false,
cancellationToken);
var updatedCron = await scheduleAdmin.UpdateScheduledJobCronAsync(
jobName: "heartbeat-every-minute",
cronExpression: "*/5 * * * *",
timeZone: "UTC",
cancellationToken);
var runNowQueued = await scheduleAdmin.RunScheduledJobNowAsync(
jobName: "heartbeat-every-minute",
cancellationToken);
Operational behavior
- Disabled schedules set
nextRunAtUtcto null until re-enabled. - Enabling recomputes
nextRunAtUtcfrom current time. RunScheduledJobNowAsyncenqueues an ad-hoc run and does not mutate cron schedule.
Typical integration pattern
Most teams wrap this service in their own application command handlers or admin APIs.
public sealed class ScheduleCommands
{
private readonly IDurableScheduleAdminService _scheduleAdmin;
public ScheduleCommands(IDurableScheduleAdminService scheduleAdmin)
{
_scheduleAdmin = scheduleAdmin;
}
public Task<bool> DisableAsync(string jobName, CancellationToken ct)
=> _scheduleAdmin.SetScheduledJobEnabledAsync(jobName, enabled: false, ct);
}