8000 GitHub - theolymp/TickerQ: TickerQ is a fast, reflection-free background task scheduler for .NET — built with source generators, EF Core integration, cron + time-based execution, and a real-time dashboard.
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

TickerQ is a fast, reflection-free background task scheduler for .NET — built with source generators, EF Core integration, cron + time-based execution, and a real-time dashboard.

License

Notifications You must be signed in to change notification settings

theolymp/TickerQ

 
 

Repository files navigation

TickerQ

NuGet NuGet Documentation

Robust. Adaptive. Precise.
TickerQ is a fast, reflection-free background task scheduler for .NET — built with source generators, EF Core integration, cron + time-based execution, and a real-time dashboard.

📚 Full Docs

👉 https://tickerq.arcenox.com


Dashboard: TickerQ Dashboard

✨ Features

  • Time and Cron Scheduling
  • Stateless Core with source generator
  • EF Core Persistence (optional)
  • Live Dashboard UI
  • Retry Policies & Throttling
  • Dependency Injection support
  • Multi-node distributed coordination

📦 Installation

Core (required)

dotnet add package TickerQ

Entity Framework Integration (optional)

dotnet add package TickerQ.EntityFrameworkCore

Dashboard UI (optional)

dotnet add package TickerQ.Dashboard

⚙️ Basic Setup

In Program.cs or Startup.cs

builder.Services.AddTickerQ(options =>
{
    options.SetMaxConcurrency(4); // Optional
    options.SetExceptionHandler<MyExceptionHandler>(); // Optional
    options.AddOperationalStore<MyDbContext>(efOpt => 
    {
        efOpt.UseModelCustomizerForMigrations(); // Applies custom model customization only during EF Core migrations
        efOpt.CancelMissedTickersOnApplicationRestart(); // Useful in distributed mode
    }); // Enables EF-backed storage
    options.AddDashboard(basePath: "/tickerq-dashboard"); // Dashboard path
    options.AddDashboardBasicAuth(); // Enables simple auth
});

app.UseTickerQ(); // Activates job processor

❗️If Not Using UseModelCustomizerForMigrations()

You must apply TickerQ configurations manually in your DbContext:

public class MyDbContext : DbContext
{
    public MyDbContext(DbContextOptions<MyDbContext> options)
        : base(options) { }

    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);

        // Apply TickerQ entity configurations explicitly
        builder.ApplyConfiguration(new TimeTickerConfigurations());
        builder.ApplyConfiguration(new CronTickerConfigurations());
        builder.ApplyConfiguration(new CronTickerOccurrenceConfigurations());

        // Alternatively, apply all configurations from assembly:
        // builder.ApplyConfigurationsFromAssembly(typeof(TimeTickerConfigurations).Assembly);
    }
}

💡 Recommendation:
Use UseModelCustomizerForMigrations() to cleanly separate infrastructure concerns from your core domain model, especially during design-time operations like migrations.
Note: If you're using third-party libraries (e.g., OpenIddict) that also override IModelCustomizer, you must either merge customizations or fall back to manual configuration inside OnModelCreating() to avoid conflicts.

Job Definition

1. Cron Job (Recurring)

public class CleanupJobs
{
    [TickerFunction(FunctionName = "CleanupLogs", CronExpression = "0 0 * * *")]
    public void CleanupLogs()
    {
        // Runs every midnight
    }
}

This uses a cron expression to run daily at midnight.


2. One-Time Job (TimeTicker)

public class NotificationJobs
{
    [TickerFunction(FunctionName = "SendWelcome")]
    public Task SendWelcome(TickerFunctionContext<string> tickerContext ,CancellationToken ct)
    {
        Console.WriteLine(tickerContext.Request); // Output: User123
        return Task.CompletedTask;
    }
}

Then schedule it:

await _timeTickerManager.AddAsync(new TimeTicker
{
    Function = "SendWelcome",
    ExecutionTime = DateTime.UtcNow.AddMinutes(1),
    Request = TickerHelper.CreateTickerRequest<string>("User123"),
    Retries = 3,
    RetryIntervals = new[] { 30, 60, 120 } // Retry after 30s, 60s, then 2min
});

3. Injecting Services in Jobs (Fully DI Support)

public class ReportJobs
{
    private readonly IReportService _reportService;

    public ReportJobs(IReportService reportService)
    {
        _reportService = reportService;
    }

    [TickerFunction(FunctionName = "GenerateDailyReport", CronExpression = "0 6 * * *")]
    public async Task GenerateDailyReport()
    {
        await _reportService.GenerateAsync();
    }
}

Dashboard UI

Enabled by adding:

options.AddDashboard(basePath: "/tickerq-dashboard");
options.AddDashboardBasicAuth(); // Optional

Accessible at /tickerq-dashboard, it shows:

  • System status
  • Active tickers
  • Job queue state
  • Cron ticker stats
  • Execution history
  • Trigger/cancel/edit jobs live

Auth config (optional):

"TickerQBasicAuth": {
  "Username": "admin",
  "Password": "admin"
}

TickerQ vs Hangfire vs Quartz.NET

Feature TickerQ Hangfire Quartz.NET
Cron scheduling ✅ Yes ✅ Yes ✅ Yes
Time-based one-time jobs ✅ Yes (TimeTicker) ⚠️ Simulated via delay ✅ Yes
Persistent job store ✅ With EF Core ✅ Yes ✅ Yes
In-memory mode ✅ Built-in ✅ Built-in ✅ Built-in
Retry/cooldown logic ✅ Advanced & configurable ⚠️ Basic retries only ⚠️ Manual
Dashboard UI ✅ First-party + real-time ✅ 8363 Basic ⚠️ Third-party required
DI support ✅ Native and seamless 🟠 Partial – type-based only ⚠️ Requires extra config
Reflection-free job discovery ✅ Roslyn-based, compile-time ❌ Uses reflection ❌ Uses reflection
Multi-node/distributed support ✅ Native with EF Core ⚠️ Depends on storage ✅ Yes
Custom tickers (plugin model) ✅ Fully extensible ❌ Not extensible ⚠️ Limited
Parallelism & concurrency control ✅ Built-in scheduler threadpool ✅ Queues/ServerCount ✅ ThreadPools
Performance under high load ✅ Optimized, no overhead ⚠️ Depends on storage/db ⚠️ Thread blocking possible
Async/await support ✅ Yes ⚠️ Limited – wrapped sync methods ✅ Yes
CancellationToken support ✅ Propagated & honored ❌ Not natively supported 🟠 Optional – must check manually

🔐 Retry & Locking

TickerQ supports:

  • Retries per job
  • Retry intervals (RetryIntervals)
  • Distributed locking (EF mode only)
  • Job ownership tracking across instances
  • Cooldown on job failure

🧪 Advanced: Manual CronTicker Scheduling

await _cronTickerManager.AddAsync(new CronTicker
{
    Function = "CleanupLogs",
    CronExpression = "0 */6 * * *", // Every 6 hours
    Retries = 2,
    RetryIntervals = new[] { 60, 300 }
});

🛠️ Developer Tips

  • Use [TickerFunction] to register jobs
  • Use FunctionName consistently across schedule and handler
  • Use CancellationToken for graceful cancellation
  • Use Request to pass dynamic data to jobs

🤝 Contribution

PRs, ideas, and issues are welcome!

  1. Fork & branch
  2. Code your change
  3. Submit a Pull Request

💖 Sponsors

Want to support this project? Become a sponsor

📄 License

MIT OR Apache 2.0 © Arcenox
You may choose either license to use this software.

About

TickerQ is a fast, reflection-free background task scheduler for .NET — built with source generators, EF Core integration, cron + time-based execution, and a real-time dashboard.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • C# 64.4%
  • Vue 21.8%
  • TypeScript 12.8%
  • Other 1.0%
0