Producer-Consumer Pattern
debt(d7/e7/b7/t5)
Closest to 'only careful code review or runtime testing' (d7), detection_hints.automated is no; queue/dispatch patterns aren't flagged by linters and issues like unbounded queues or lost jobs only surface under load.
Closest to 'cross-cutting refactor across the codebase' (e7), the quick_fix involves moving operations to a job queue, introducing workers, and acknowledgement handling — touches multiple files and infra components beyond a single patch.
Closest to 'strong gravitational pull' (b7), applies_to spans web/cli/queue-worker; once adopted, async boundaries shape how features are designed across the system.
Closest to 'notable trap (documented gotcha)' (t5), the misconception (thinking it's only for multi-threaded apps) and common mistakes (unbounded queues, unacknowledged jobs) are well-documented gotchas most devs learn after hitting them.
TL;DR
Explanation
Pattern: producers push work items to a bounded queue; consumers pull and process them. The queue acts as a buffer. Benefits: decoupling (producers don't wait for consumers), load levelling (queue absorbs spikes), parallelism (multiple consumers). PHP implementation: Redis LPUSH/BRPOP, database queue (Laravel Queue, Symfony Messenger), message broker (RabbitMQ, Kafka). Bounded queue: when full, producer blocks or drops. Unbounded queue: memory risk. Back-pressure: signal to producers to slow down when queue grows. Dead letter queue: failed items after max retries.
Common Misconception
Why It Matters
Common Mistakes
- Unbounded queue growing indefinitely — always set max queue size.
- Not handling consumer crashes — jobs are lost unless the queue acknowledges.
- Single consumer bottleneck — scale consumers independently of producers.
Code Examples
// Synchronous — producer blocks on slow processing:
foreach ($requests as $req) {
processSlowly($req); // Blocks next request
}
// Async with Redis queue:
// Producer:
$redis->lpush('jobs', json_encode(['type' => 'email', 'to' => $email]));
// Consumer (worker process):
while (true) {
[$queue, $job] = $redis->brpop('jobs', 5); // Block up to 5s
if ($job) processJob(json_decode($job, true));
}