[JobConfig] Attribute
A class-level attribute that sets default behavior for a job. Applied to IJob<T> or IRecurringJob implementations. Per-call JobOptions take priority over these defaults.
Namespace: Zeridion.Flare · Assembly: Zeridion.Flare.dll
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
public sealed class JobConfigAttribute : Attribute
{
public string Queue { get; set; } = "default";
public int MaxAttempts { get; set; } = 3;
public int TimeoutSeconds { get; set; } = 1800;
public string? CronSchedule { get; set; }
}
Properties
| Property | Type | Default | Description |
|---|---|---|---|
Queue | string | "default" | Default queue name for this job type. |
MaxAttempts | int | 3 | Default maximum retry attempts before dead letter. |
TimeoutSeconds | int | 1800 | Default execution timeout in seconds (30 minutes). |
CronSchedule | string? | null | Cron expression for recurring jobs. Only for IRecurringJob. |
How it works
The JobTypeRegistry scans assemblies at startup (triggered by AddZeridionFlare) and reads [JobConfig] attributes from every discovered job class. The attribute values become the defaults for that job type.
When a job is enqueued, the SDK resolves settings in this order:
JobOptionspassed to theIJobClientmethod (highest priority)[JobConfig]attribute on the job class (or hardcoded defaults if no attribute)
If no [JobConfig] is applied, the attribute defaults ("default", 3, 1800) are used. See Option precedence for details.
Queue
Assign a job type to a specific queue. Workers can be configured to poll only certain queues, enabling workload isolation:
[JobConfig(Queue = "email")]
public class SendWelcomeEmail : IJob<NewUserEvent>
{
public async Task ExecuteAsync(NewUserEvent payload, JobContext ctx)
{
// This job always goes to the "email" queue unless overridden by JobOptions
}
}
MaxAttempts
Set the maximum number of execution attempts. After all attempts are exhausted, the job moves to DeadLetter:
[JobConfig(MaxAttempts = 5)]
public class ProcessPayment : IJob<PaymentPayload>
{
// Will retry up to 4 times (5 total attempts) with exponential backoff
}
TimeoutSeconds
Set the maximum execution time in seconds. The CancellationToken in JobContext is cancelled when the timeout elapses:
[JobConfig(TimeoutSeconds = 300)] // 5 minutes
public class GeneratePdfReport : IJob<ReportPayload>
{
// Worker cancels the token after 5 minutes
}
CronSchedule
Set a cron expression for IRecurringJob implementations. Uses standard 5-field cron format (parsed by the Cronos library). This property is ignored on IJob<T> classes.
[JobConfig(CronSchedule = "0 3 * * *")] // Daily at 3:00 AM UTC
public class CleanupExpiredSessions : IRecurringJob
{
public async Task ExecuteAsync(JobContext ctx)
{
// Runs once per day at 3 AM
}
}
Usage examples
Payload job with all options
[JobConfig(Queue = "critical", MaxAttempts = 10, TimeoutSeconds = 600)]
public class SyncInventory : IJob<InventoryPayload>
{
private readonly IInventoryService _inventory;
public SyncInventory(IInventoryService inventory) => _inventory = inventory;
public async Task ExecuteAsync(InventoryPayload payload, JobContext ctx)
{
await _inventory.SyncAsync(payload.WarehouseId, ctx.CancellationToken);
}
}
Recurring job with queue and schedule
[JobConfig(CronSchedule = "*/15 * * * *", Queue = "maintenance", TimeoutSeconds = 120)]
public class PurgeStaleTokens : IRecurringJob
{
private readonly ITokenStore _tokens;
public PurgeStaleTokens(ITokenStore tokens) => _tokens = tokens;
public async Task ExecuteAsync(JobContext ctx)
{
var count = await _tokens.PurgeExpiredAsync(ctx.CancellationToken);
ctx.Logger.LogInformation("Purged {Count} stale tokens", count);
}
}
See also
- JobOptions — per-call overrides (higher priority than
[JobConfig]) - ZeridionFlareOptions — global options (not currently used in the cascade)
- Option precedence — the two-level cascade
- IRecurringJob — the interface that uses
CronSchedule