Derniers tips / Mémos
Modélise nativement « exactement l'un de ces types », avec un switch exhaustif vérifié par le compilateur.
Fin des state machines générées par le compilateur : moins d'allocations et des stack traces enfin lisibles.
Recherche sémantique directement dans SQL Server 2025, sans base vectorielle séparée, en LINQ typé.
Framework UI cross-platform pour .NET : Windows, macOS, Linux, iOS, Android et WebAssembly.
Découvrez les nouvelles APIs asynchrones pour la compression ZIP et les améliorations de performance dans .NET 10
TickerQ : Scheduler de tâches haute performance pour .NET
TickerQ fournit une planification de jobs basée sur le temps ou des expressions cron, un cœur stateless optimisé via source generators, une persistance EF Core optionnelle et un dashboard temps réel pour suivre l'exécution.
Présentation
Librairie open‑source orientée performance et observabilité : pas de réflexion à l'exécution, coordination multi‑nœuds, politiques de retry et throttling intégrées, dashboard embarqué.
Installation
# Core
dotnet add package TickerQ
# EF Core (optionnel)
dotnet add package TickerQ.EntityFrameworkCore
# UI Dashboard (optionnel)
dotnet add package TickerQ.DashboardTous les packages doivent être alignés sur la même version (depuis >= v2.2.0).
Fonctionnalités clés
- Planification Cron et temporelle (one‑shot)
- Cœur stateless + source generator (pas de réflexion runtime)
- Persistance EF Core optionnelle
- Dashboard temps réel (suivi, inspection, statut)
- Retries configurables + intervalles progressifs
- Throttling via contrôle de concurrence global
- Injection de dépendances native
- Coordination distribuée multi‑nœuds
Configuration de base
Enregistrement des services et activation du pipeline d'exécution. Le dashboard peut être monté sous un chemin dédié avec authentification basique.
builder.Services.AddTickerQ(options =>
{
options.SetMaxConcurrency(10);
options.AddOperationalStore<MyDbContext>(efOpt =>
{
efOpt.SetExceptionHandler<MyExceptionHandlerClass>();
efOpt.UseModelCustomizerForMigrations();
});
options.AddDashboard(ui =>
{
ui.BasePath = "/tickerq-dashboard";
ui.AddDashboardBasicAuth();
});
});
app.UseTickerQ(); // activate processorsDéfinition & planification de jobs
Un job récurrent se définit via l'attribut [TickerFunction]; les occurrences sont planifiées soit par temps absolu (TimeTicker) soit via une expression cron (CronTicker).
public class CleanupJobs(ICleanUpService cleanUpService)
{
private readonly ICleanUpService _cleanUpService = cleanUpService;
[TickerFunction(functionName: "CleanupLogs", cronExpression: "0 0 * * *" )]
public async Task CleanupLogs(TickerFunctionContext<string> ctx, CancellationToken ct)
{
var file = ctx.Request; // e.g. cleanup_example_file.txt
await _cleanUpService.CleanOldLogsAsync(file, ct);
}
}// One-shot time based job
await _timeTickerManager.AddAsync(new TimeTicker
{
Function = "CleanupLogs",
ExecutionTime = DateTime.UtcNow.AddMinutes(1),
Request = TickerHelper.CreateTickerRequest<string>("cleanup_example_file.txt"),
Retries = 3,
RetryIntervals = new[] { 30, 60, 120 },
});
// Recurring cron job
await _cronTickerManager.AddAsync(new CronTicker
{
Function = "CleanupLogs",
Expression = "0 */6 * * *", // every 6 hours
Request = TickerHelper.CreateTickerRequest<string>("cleanup_example_file.txt"),
Retries = 2,
RetryIntervals = new[] { 60, 300 }
});Persistance EF Core
Utilisez UseModelCustomizerForMigrations pour intégrer proprement la configuration. Sans cela appliquez manuellement les configurations dans OnModelCreating.
public class MyDbContext : DbContext
{
public MyDbContext(DbContextOptions<MyDbContext> options) : base(options) { }
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
// Explicit configuration if not using UseModelCustomizerForMigrations
builder.ApplyConfiguration(new TimeTickerConfigurations());
builder.ApplyConfiguration(new CronTickerConfigurations());
builder.ApplyConfiguration(new CronTickerOccurrenceConfigurations());
// or: builder.ApplyConfigurationsFromAssembly(typeof(TimeTickerConfigurations).Assembly);
}
}Retries & Throttling
Les propriétés Retries + RetryIntervals gèrent les relances. Le throttling global s'obtient via SetMaxConcurrency ; combinez avec une granularité fonction par design.
// Example of retry intervals & throttling like behaviour via configuration
await _timeTickerManager.AddAsync(new TimeTicker
{
Function = "ImportData",
ExecutionTime = DateTime.UtcNow.AddSeconds(30),
Request = TickerHelper.CreateTickerRequest<string>("import_batch_42"),
Retries = 5,
RetryIntervals = new[] { 10, 30, 60, 120, 300 },
// (Pseudo) throttle approach: keep Function concurrency low via SetMaxConcurrency globally
});Dashboard temps réel
Surveille exécutions, états, erreurs et facilite le diagnostic en production. Authentifiez l'accès et limitez le chemin d'exposition.
// Add dashboard with basic auth (see real docs for advanced auth)
builder.Services.AddTickerQ(o =>
{
o.AddDashboard(ui =>
{
ui.BasePath = "/tickerq-dashboard";
ui.AddDashboardBasicAuth();
});
});Bonnes pratiques
- Isoler le domaine: Gardez les handlers de jobs fins, déléguez la logique métier à des services testables.
- Nommer les functions clairement: Facilite la corrélation entre planification et implémentation.
- Limiter la concurrence globale: Évite la saturation CPU/IO sur charges importantes.
- Renseigner les RetryIntervals: Contrôle la pression sur les dépendances externes.
- Centraliser la configuration EF: Réduit le risque de divergence lors des migrations.
- Sécuriser le dashboard: Protège les métadonnées d'exécution et l'observabilité.
Résumé
TickerQ est adapté lorsque vous avez besoin d'un scheduler .NET extensible, observable et sans overhead de réflexion, avec prise en charge native des scénarios distribués et une intégration EF Core rapide.