JobOptions
Per-call overrides passed to IJobClient methods. Any property left as null falls through to the next level in the option precedence chain.
Namespace: Zeridion.Flare · Assembly: Zeridion.Flare.dll
public sealed class JobOptions
{
public string? Queue { get; set; }
public int? MaxAttempts { get; set; }
public TimeSpan? Timeout { get; set; }
public Dictionary<string, string>? Tags { get; set; }
public string? IdempotencyKey { get; set; }
}
Properties
| Property | Type | Default | Description |
|---|---|---|---|
Queue | string? | null | Override the queue name for this job. |
MaxAttempts | int? | null | Override the maximum retry attempts. |
Timeout | TimeSpan? | null | Override the job execution timeout. |
Tags | Dictionary<string, string>? | null | Custom key-value metadata attached to the job. |
IdempotencyKey | string? | null | Prevents duplicate jobs with the same key. |
JobOptions has the highest priority. Values set here override the [JobConfig] attribute defaults and hardcoded SDK defaults. See Option precedence for the full resolution order.
Queue
Override which queue the job is assigned to. Workers can be configured to poll specific queues, enabling workload isolation:
await jobs.EnqueueAsync<SendWelcomeEmail>(payload, new JobOptions
{
Queue = "email-priority"
});
MaxAttempts
Override how many times the job will be attempted before moving to the dead letter queue:
await jobs.EnqueueAsync<ProcessPayment>(payload, new JobOptions
{
MaxAttempts = 1 // no retries — fail immediately on error
});
Timeout
Override the maximum execution time. If the job runs longer than this, the CancellationToken in JobContext is cancelled:
await jobs.EnqueueAsync<GenerateReport>(payload, new JobOptions
{
Timeout = TimeSpan.FromMinutes(60) // allow up to 1 hour
});
Tags
Arbitrary key-value metadata attached to the job. Tags are stored with the job, returned in JobStatus.Tags, and visible in the dashboard. Use them for filtering, searching, and correlation:
await jobs.EnqueueAsync<SendWelcomeEmail>(payload, new JobOptions
{
Tags = new Dictionary<string, string>
{
["user_id"] = user.Id,
["campaign"] = "onboarding-q1",
["source"] = "api"
}
});
IdempotencyKey
Prevents duplicate jobs. If a job with the same idempotency key already exists, the API returns a 409 Conflict response and the SDK throws FlareConflictException.
This is critical for scenarios where the same event might trigger multiple enqueue calls — webhook handlers, payment processing, or retry logic in the caller:
await jobs.EnqueueAsync<ProcessPayment>(payload, new JobOptions
{
IdempotencyKey = $"payment:{payload.OrderId}"
});
The idempotency key is scoped to the project (API key). Two different projects can use the same key without conflict.
Usage example
A complete example combining multiple options:
app.MapPost("/orders/{id}/fulfill", async (string id, IJobClient jobs) =>
{
var payload = new FulfillmentPayload { OrderId = id };
var jobId = await jobs.EnqueueAsync<FulfillOrder>(payload, new JobOptions
{
Queue = "fulfillment",
MaxAttempts = 3,
Timeout = TimeSpan.FromMinutes(10),
IdempotencyKey = $"fulfill:{id}",
Tags = new Dictionary<string, string>
{
["order_id"] = id,
["priority"] = "high"
}
});
return Results.Accepted(value: new { job_id = jobId });
});
See also
- [JobConfig] Attribute — class-level defaults (lower priority than
JobOptions) - ZeridionFlareOptions — global options (not currently used in the cascade)
- Option precedence — the two-level cascade
- Idempotency guide — patterns for preventing duplicate work