HostLoom.Scheduling
0.17.0
dotnet add package HostLoom.Scheduling --version 0.17.0
NuGet\Install-Package HostLoom.Scheduling -Version 0.17.0
<PackageReference Include="HostLoom.Scheduling" Version="0.17.0" />
<PackageVersion Include="HostLoom.Scheduling" Version="0.17.0" />
<PackageReference Include="HostLoom.Scheduling" />
paket add HostLoom.Scheduling --version 0.17.0
#r "nuget: HostLoom.Scheduling, 0.17.0"
#:package HostLoom.Scheduling@0.17.0
#addin nuget:?package=HostLoom.Scheduling&version=0.17.0
#tool nuget:?package=HostLoom.Scheduling&version=0.17.0
HostLoom.Scheduling
HostLoom.Scheduling is the backend-neutral scheduled-job kernel: the job contract
IScheduledJob, the triggers that decide when a schedule runs, the Scheduler that waits on a
TimeProvider and runs each schedule sequentially, and the IScheduleGuard contract that decides
which instance runs a schedule marked exclusive. The package references only
Microsoft.Extensions.Logging.Abstractions; every runtime type has a public constructor, so a
scheduler composes without a container.
A schedule is a loop, not a queue. Each schedule runs one job at a time in this process: a run
never starts while the previous run of the same schedule is still executing, and a run that is
already late starts at once without replaying the occurrences it missed. Across processes, an
Exclusive schedule claims itself through the guard before every run and is skipped, never queued,
when another instance holds the claim.
var nightly = new ScheduleDefinition(
"catalog:rebuild",
ScheduleTrigger.Cron("0 0 2 * * *"), // 02:00 UTC every day
async (run, token) => await RebuildCatalogAsync(token),
new ScheduleOptions { Exclusive = true, Timeout = TimeSpan.FromMinutes(30) });
var sync = new ScheduleDefinition(
"inventory:sync",
ScheduleTrigger.FixedDelay(TimeSpan.FromSeconds(30)), // 30 s after each completion
async (run, token) => await SyncInventoryAsync(run.DueAt, token));
await using var scheduler = new Scheduler(new SchedulingOptions(), [nightly, sync], guard);
await scheduler.StartAsync();
A schedule without Exclusive runs on every instance that hosts it. An Exclusive schedule runs
on one instance per occurrence: the claim is kept past the run until the lease ends or this
instance's next occurrence is due, whichever comes first, so a slower instance reaching the same
occurrence is refused rather than running the job again. Choose the lease as at least the clock
skew between instances plus the run's duration, and no more than the period.
Three trigger shapes follow the Spring conventions. Cron takes five fields (minute, hour, day of
month, month, day of week) or six with a leading seconds field, with *, lists, ranges, steps,
month and day names, and ?; when both day fields are restricted an occurrence matches either, as
in Vixie cron, and occurrences are evaluated in the zone given to the trigger, UTC by default.
FixedRate counts each period from the previous due time, so a slow run does not drift the
schedule. FixedDelay counts from the previous completion, so two runs are always separated by at
least the delay.
A run receives a ScheduledRun (name, due time, start time, sequence) and a token that is
cancelled when the host stops, when ScheduleOptions.Timeout elapses, or when an exclusive claim
is lost. An exception ends the run as Failed; the schedule continues. Outcomes are recorded per
schedule (Scheduler.GetState), on the hostloom.schedule.run.duration histogram by outcome, and
in the log events listed in SchedulingEvents. A guard that throws skips the run as
GuardFailed: a job that must not run twice cannot run when nothing can say whether another
instance already does.
StopAsync(token) bounds the wait for running jobs and cancellation callbacks. When that bound
expires, later DisposeAsync() preserves the abandonment and returns without waiting again.
The jobs may still finish; cancellation resources are released after their loops end. Direct
disposal without an earlier abandoned stop waits for the loops, so jobs should honor cancellation.
SchedulingOptions.Enabled = false runs nothing and says so at startup, for a deployment that
keeps its registrations but must not execute jobs. SchedulingProbe.Describe(scheduler) reports
the composition and the current state of every schedule without running anything. Install
HostLoom.Scheduling.DependencyInjection to register the scheduler with the built-in .NET
container and HostLoom.Scheduling.Locking to guard exclusive schedules with the HostLoom
distributed lock.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.12)
NuGet packages (4)
Showing the top 4 NuGet packages that depend on HostLoom.Scheduling:
| Package | Downloads |
|---|---|
|
HostLoom.Scheduling.DependencyInjection
Microsoft.Extensions.DependencyInjection registration, per-run scopes, options validation, and hosting for HostLoom scheduling. |
|
|
HostLoom.Scheduling.Leadership
Runs exclusive HostLoom schedules on the elected leader only, without a lock round trip per occurrence. |
|
|
HostLoom.Scheduling.Testing
Scripted schedule guard and claim recording for testing HostLoom scheduling consumers without a backend. |
|
|
HostLoom.Scheduling.Locking
Runs exclusive HostLoom schedules on one instance at a time by claiming them through the HostLoom distributed lock. |
GitHub repositories
This package is not used by any popular GitHub repositories.