Message Queue Patterns
debt(d9/e7/b7/t7)
Closest to 'silent in production until users hit it' (d9). The detection_hints field explicitly states 'automated: no'. Misapplied queue patterns — such as request-reply without timeout or competing consumers on an ordered queue — produce no compiler errors, no linter warnings, and no SAST signals. Problems surface only under real load or when messages are lost/delayed in production.
Closest to 'cross-cutting refactor across the codebase' (e7). Queue patterns are architectural choices that permeate producer code, consumer code, broker configuration, monitoring, and retry/dead-letter logic. Switching from a naive async-call model to correct named patterns (scatter-gather, competing consumers, dead-letter) requires touching multiple services and infrastructure components — well beyond a single-file fix.
Closest to 'strong gravitational pull' (e7). The term applies to web, cli, and queue-worker contexts, meaning every part of the system interacts with messaging infrastructure. The chosen patterns shape how producers, consumers, brokers, and monitoring are designed. Every future feature that involves async communication is constrained by the original pattern choices.
Closest to 'serious trap — contradicts how a similar concept works elsewhere' (t7). The canonical misconception states developers treat queues as 'just async function calls', missing the richer pattern space entirely. This directly maps to t7: competent developers familiar with simple async invocation will naturally underestimate queue complexity, leading to real bugs like infinite hangs (request-reply without timeout) or ordering violations (competing consumers on ordered queues).
TL;DR
Explanation
Key patterns: (1) Competing consumers: multiple consumers on one queue, each processes different messages — horizontal scaling. (2) Scatter-gather: broadcast to multiple services, aggregate responses. (3) Request-reply: producer sends and waits for reply on a correlation ID — makes async look synchronous. (4) Message filter: consumer silectively processes messages matching criteria. (5) Dead letter: failed messages routed to DLQ. (6) Retry with backoff: failed processing retried with increasing delay. (7) Priority queue: high-priority messages processed first. (8) Message expiry: TTL after which message is discarded. These are from Enterprise Integration Patterns (Hohpe & Woolf).
Common Misconception
Why It Matters
Common Mistakes
- Request-reply via queue without timeout — hangs forever if reply doesn't come.
- Competing consumers on an ordered queue — breaks message ordering.
- Priority queue without monitoring — high-priority messages don't help if consumers are busy.
Code Examples
// Request-reply without timeout/correlation:
$replyQueue = 'reply.' . uniqid();
$producer->send('service.requests', ['reply_to' => $replyQueue, 'data' => $data]);
$reply = $consumer->waitFor($replyQueue); // Hangs if service is down
// Request-reply with timeout and correlation ID:
$correlationId = Uuid::v4();
$producer->send('service.requests', [
'correlation_id' => $correlationId,
'reply_to' => 'my-service.replies',
'data' => $data,
]);
$reply = $consumer->waitFor('my-service.replies', $correlationId, timeout: 5);
if (!$reply) throw new ServiceTimeoutException();