Skip to content

Queue attributes

#[proc_macro_derive(Queues, attributes(queues, queue))]

Applies to a fieldless enum only. The derive generates impl QueueSet and nothing else — in particular it does not add QueueSet’s supertraits, so the enum needs #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Queues)].

Optional. Both keys are optional.

Key Type Valid range Default
prefix string literal non-empty; names become "{prefix}.{name}" none
crate string literal (module path) a valid path; a bare name gets a leading ::; crate::, self:: and super:: are used verbatim auto: ::queuey::__core if the caller depends on queuey, else ::queuey_core

crate exists for re-exporting wrappers around queuey. Application code never needs it.

Optional. Every key is optional.

Key Type Valid range Default
name string literal non-empty snake_case of the variant
prefetch integer 1..=65535 16
durable bool true / false true
message_ttl duration literal greater than zero none
max_priority integer 0..=255; 0 disables priorities 10 (DEFAULT_MAX_PRIORITY)
retry(...) nested list see Job attributes RetryPolicy::default(), which is no retries

Snake-casing handles acronyms: SendEmails becomes send_emails and HTTPCalls becomes http_calls.

Every duration-valued key takes a string literal parsed at macro time: an integer followed by a unit, where the unit is one of ms, s, m, h or d. A bare integer means seconds. Whitespace is ignored, so " 5 s " and "5 ms" both parse. The value resolves to whole milliseconds.

Accepted: "500ms", "30s", "2 m", "1h", "7d", "30".

Rejected: "", " ", "s", "abc", "1x", "1.5s", "-1s", "1sm", "1 m s", "ms1", "+2s", anything overflowing u64 milliseconds, and zero everywhere.

Every mistake is an error pointing at the offending token.

Mistake Message
Not an enum #[derive(Queues)] can only be applied to enums
No variants #[derive(Queues)] requires at least one variant
A variant with fields queue variants must not have fields
Generic enum generic queue enums are not supported
Mistake Message
prefix = "" `prefix` must not be empty
name = "" `name` must not be empty
Two variants resolving to one name duplicate queue name `myapp.emails`, with a note `myapp.emails` is first used here
A variant whose snake_case name is empty queue name is empty; give the variant a #[queue(name = "...")]
Mistake Message
prefetch = 0 `prefetch = 0` means unlimited in AMQP; omit the attribute or use a positive value
prefetch negative or above 65535 `prefetch` must be an integer between 1 and 65535
max_priority out of range or not an integer `max_priority` must be an integer in 0..=255
message_ttl = "0s" `message_ttl` must be greater than zero: a zero TTL discards every message the moment it is published
An unparseable duration invalid duration `30 fortnights`: expected an integer with an optional unit (`ms`, `s`, `m`, `h`, `d`), for example "500ms", "30s" or "2m"
Mistake Message
A repeated key duplicate key `prefetch`
An unknown key in #[queue(...)] unknown key `concurrency` in `#[queue(...)]`, expected one of `name`, `prefetch`, `durable`, `message_ttl`, `max_priority`, `retry`
An unknown key in #[queues(...)] expects prefix or crate
pub trait QueueSet:
Copy + Clone + Eq + std::hash::Hash + std::fmt::Debug + Send + Sync + 'static
{
fn all() -> &'static [Self];
fn name(&self) -> &'static str;
fn config(&self) -> QueueConfig;
fn from_name(name: &str) -> Option<Self>;
}

all() returns the variants in declaration order. from_name is provided by the trait as a linear scan of all().

pub struct QueueConfig {
pub name: String,
pub prefetch: u16,
pub retry: RetryPolicy,
pub durable: bool,
pub message_ttl: Option<Duration>,
pub max_priority: Option<u8>,
}
impl QueueConfig {
pub fn new(name: impl Into<String>) -> Self;
pub fn prefetch(mut self, prefetch: u16) -> Self;
pub fn retry(mut self, retry: RetryPolicy) -> Self;
pub fn durable(mut self, durable: bool) -> Self;
pub fn message_ttl(mut self, ttl: Duration) -> Self;
pub fn max_priority(mut self, levels: u8) -> Self; // 0 => None
}

QueueConfig::new defaults to prefetch 16, RetryPolicy::default(), durable, no TTL, and Some(DEFAULT_MAX_PRIORITY).

pub const DEFAULT_MAX_PRIORITY: u8 = 10;

Ten levels, because RabbitMQ recommends at most ten.

Queues for what these settings mean in practice, and queuey_core::queue on docs.rs.