Skip to content

ZeroAlloc-Net/ZeroAlloc.Scheduling

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

110 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ZeroAlloc.Scheduling

NuGet Build License: MIT AOT GitHub Sponsors

ZeroAlloc.Scheduling is a source-generated background job scheduler for .NET 8 and .NET 10. Decorate any class with [Job] and the source generator wires up the executor, DI registration, and recurring startup automatically — no reflection, no convention scanning at runtime.

Install

The source generator is bundled into the main package — a single PackageReference is all you need:

dotnet add package ZeroAlloc.Scheduling
dotnet add package ZeroAlloc.Scheduling.InMemory   # or EfCore / Redis

The standalone ZeroAlloc.Scheduling.Generator package is still published for backwards compatibility with existing direct PackageReferences, but new consumers should reference only ZeroAlloc.Scheduling.

Example

// 1. Define a job — the generator picks it up automatically
[Job(Every = Every.Hour)]
public sealed class CleanupExpiredSessionsJob : IJob
{
    private readonly ISessionRepository _repo;
    public CleanupExpiredSessionsJob(ISessionRepository repo) => _repo = repo;

    public async ValueTask ExecuteAsync(JobContext ctx, CancellationToken ct)
        => await _repo.DeleteExpiredAsync(ct);
}

// 2. Register — generated AddCleanupExpiredSessionsJob() wires executor + recurring startup
services.AddScheduling()
        .WithInMemoryStore()
        .AddCleanupExpiredSessionsJob();

// 3. Enqueue a one-off job from application code
public class OrderService(IScheduler scheduler)
{
    public async Task CompleteOrderAsync(Order order, CancellationToken ct)
    {
        await ProcessAsync(order, ct);
        await scheduler.EnqueueAsync(new SendOrderConfirmationJob(order.Id), ct);
    }
}

Performance

Head-to-head vs Coravel 5.0.4 (de-facto in-process scheduler) and a hand-rolled BackgroundService + Timer baseline. .NET 10.0.7, i9-12900HK, BenchmarkDotNet v0.15.4.

Operation Coravel Naive Timer ZA.Scheduling
Job registration 8,211 ns / 696 B per call — (compile-time) compile-time, 0 ns runtime
Single dispatch (registration only) 0.01 ns 0.25 ns (parity, JIT-inlined)

Honest reading: Coravel's Schedule() is a runtime call that allocates a queue entry; ZA.Scheduling's [Job] registration happens at compile time via source generation — no equivalent runtime cost. For dispatch overhead, ZA matches a hand-written Timer (both inlined to near-zero). The value of the abstraction is [Job] itself (declarative retries / cron / store-backed persistence), not raw dispatch speed.

Full methodology + design analysis: docs/performance.md.

Features

  • Source generator[Job] on a class emits a typed executor, DI extension method, and optional recurring startup (IHostedService)
  • Recurring jobs[Job(Cron = "0 * * * *")] or [Job(Every = Every.Hour)] — scheduled via Cronos at startup
  • Retry with backoff — exponential retry up to MaxAttempts (per-job or global); dead-letters after exhaustion
  • Multiple backends — InMemory (dev/test), EF Core (SQL Server / PostgreSQL / SQLite), Redis
  • Dashboard — embedded HTML/JS dashboard via app.MapJobsDashboard("/jobs")
  • Blazor component<JobsDashboard> Razor component for integration into Blazor apps
  • Mediator bridge[Job] + IRequest<Unit> auto-registers MediatorJobTypeExecutor<T>, routing execution through ZeroAlloc.Mediator pipeline behaviors
  • Native AOT compatible — no reflection at runtime; all dispatch resolved at compile time

Dashboard

An embedded HTML/JS dashboard — summary cards for each job state, a live-refreshing table with per-row requeue / delete actions, and fully responsive down to mobile widths.

app.MapJobsDashboard("/jobs");

// Optional: protect with auth
app.MapJobsDashboard("/jobs").RequireAuthorization("AdminPolicy");

Scheduler dashboard — desktop

Tablet (768 × 1024) and mobile (375 × 812) captures live in docs/screenshots/.

See Dashboard for the full endpoint reference and the Blazor component.

Packages

Package Description
ZeroAlloc.Scheduling Core interfaces, worker service, scheduler
ZeroAlloc.Scheduling.Generator Source generator (analyzer reference)
ZeroAlloc.Scheduling.InMemory In-process store for development and testing
ZeroAlloc.Scheduling.EfCore EF Core store (SQL Server, PostgreSQL, SQLite)
ZeroAlloc.Scheduling.Redis Redis store for distributed deployments
ZeroAlloc.Scheduling.Dashboard Embedded HTML dashboard (MapJobsDashboard)
ZeroAlloc.Scheduling.Dashboard.Blazor Blazor component library
ZeroAlloc.Scheduling.Mediator ZeroAlloc.Mediator bridge

Documentation

Page Description
Getting Started Install and schedule your first job in five minutes
Source Generator [Job], Every, Cron, generated extension methods
Backends InMemory, EF Core, and Redis store configuration
Dashboard Embedded HTML dashboard and Blazor component
Mediator Bridge Route job execution through ZeroAlloc.Mediator
Diagnostics ZASCH001 compiler warning reference
Performance Throughput, allocation profile, and tuning guide

License

MIT

About

Source-generated background job scheduler for .NET 8 and .NET 10. Decorate a class with [Job] and the Roslyn generator wires up the executor, DI registration, and recurring startup — no reflection at runtime.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors