Configuration

Queue defaults, per-job overrides, and worker tuning — every option, with its default value.

Options are layered: QueueOpts sets the defaults for the whole queue, JobOptions overrides them per job, and WorkerOpts tunes the process that consumes them.

Queue options

QueueOpts is passed to Queue::new and applies to every job that does not override it.

use kiomq::{BackOffJobOptions, BackOffOptions, KeepJobs, QueueEventMode, QueueOpts,
            RemoveOnCompletionOrFailure};

let queue_opts = QueueOpts {
    attempts: 2,
    default_backoff: Some(BackOffJobOptions::Opts(BackOffOptions {
        type_: Some("exponential".into()),
        delay: Some(200),
    })),
    remove_on_fail: Some(RemoveOnCompletionOrFailure::Opts(KeepJobs {
        age: Some(3600), // keep for 1 hour
        count: None,
    })),
    event_mode: Some(QueueEventMode::PubSub),
    ..Default::default()
};

let queue = Queue::new(store, Some(queue_opts)).await?;
FieldTypeDefaultNotes
attemptsu641Default attempt limit for jobs that don’t set their own
default_backoffOption<BackOffJobOptions>NoneRetry delay strategy for the whole queue
remove_on_completeOption<RemoveOnCompletionOrFailure>NoneRetention for completed jobs; None keeps them
remove_on_failOption<RemoveOnCompletionOrFailure>NoneRetention for permanently failed jobs
event_modeOption<QueueEventMode>StreamStream (replayable) or pub/sub (broadcast-only) delivery
repeatOption<Repeat>NoneDefault repeat policy for every job on the queue

Job options

JobOptions is the third argument to add_job, and the second element of each bulk_add tuple. Anything left at its default falls back to the queue.

use kiomq::{JobDelay, JobOptions};

let opts = JobOptions {
    attempts: 5,
    priority: 1,                          // lower runs first; 0 = no priority
    delay: JobDelay::TimeMilis(30_000),   // eligible in 30s
    ..Default::default()
};

queue.add_job("send-invoice", payload, Some(opts)).await?;
FieldTypeDefaultNotes
priorityu640Lower values run first. 0 means “no priority”
delayJobDelayTimeMilis(0)Run now, after N ms, or from a cron expression
idOption<u64>NoneExplicit job ID; the store assigns one when None
attemptsu640 → queue defaultMaximum attempts before permanent failure
remove_on_completeOption<…>inheritOverrides the queue retention policy
remove_on_failOption<…>inheritOverrides the queue retention policy
backoffOption<BackOffJobOptions>inheritPer-job retry delay strategy
repeatOption<Repeat>inheritRe-enqueue the job after each run

Worker options

use kiomq::WorkerOpts;

let opts = WorkerOpts {
    concurrency: 8,
    lock_duration: 120_000,   // long-running jobs
    lock_renew_time: 60_000,  // roughly half of lock_duration
    ..Default::default()
};

let worker = Worker::new_async(&queue, processor, Some(opts))?;
FieldTypeDefaultNotes
concurrencyusizelogical CPU countJobs processed simultaneously per worker
lock_durationu6430_000Milliseconds a job lock is held before the job counts as stalled
lock_renew_timeu6415_000When the lock is renewed. Half of lock_duration suits most cases
stalled_intervalu6430_000How often the worker scans for stalled jobs
max_stalled_countu641Stalled recoveries allowed before the job is failed
autorunboolfalseCall run() from the constructor instead of by hand
metrics_update_intervalu64100How often per-worker metrics are published to the store
Note

autorun defaults to false so that constructing a worker never implicitly starts consuming jobs. Call worker.run() when your service is ready.

Retention policies

RemoveOnCompletionOrFailure accepts three shapes:

use kiomq::{KeepJobs, RemoveOnCompletionOrFailure};

// Delete the record as soon as the job settles.
RemoveOnCompletionOrFailure::Bool(true);

// Keep it forever (the default).
RemoveOnCompletionOrFailure::Bool(false);

// Keep at most 1 000 records, pruning the oldest.
RemoveOnCompletionOrFailure::Int(1_000);

// Keep for an hour, and at most 500 records.
RemoveOnCompletionOrFailure::Opts(KeepJobs {
    age: Some(3_600),
    count: Some(500),
});

A common production pairing is to drop completed jobs immediately and keep failures for a day so you can inspect them:

let queue_opts = QueueOpts {
    remove_on_complete: Some(RemoveOnCompletionOrFailure::Bool(true)),
    remove_on_fail: Some(RemoveOnCompletionOrFailure::Opts(KeepJobs {
        age: Some(86_400),
        count: None,
    })),
    ..Default::default()
};

Event delivery mode

use kiomq::QueueEventMode;

QueueEventMode::Stream;  // default — persistent, replayable by late subscribers
QueueEventMode::PubSub;  // broadcast-only — listeners miss events fired before they attached

Use Stream when a consumer needs to catch up after a restart; use PubSub when you only care about live events and want to avoid retaining them. See Events .

Custom backoff strategies

Two strategies are registered out of the box: "exponential" (2^attempt * delay) and "fixed" (constant delay). Register your own by name on the queue:

use std::sync::Arc;

queue.register_backoff_strategy("decorrelated", |_attempt| {
    Arc::new(|attempt: i64| {
        // your formula: (attempt) -> delay in milliseconds
        (attempt * 250).min(30_000)
    })
});

// Then reference it by name from job or queue options.
let opts = JobOptions {
    backoff: Some(BackOffJobOptions::Opts(BackOffOptions {
        type_: Some("decorrelated".into()),
        delay: Some(250),
    })),
    ..Default::default()
};

Registration is idempotent: a name that already exists is not replaced.

Esc

Type to search the docs.