strnoar/bqueuebundle
BQueueBundle is a Laravel/PHP package for managing background queues and asynchronous jobs. It provides a simple API for dispatching work, configuring queue connections, and running workers, helping keep time-consuming tasks out of your request cycle.
This is a Symfony bundle, not a Laravel package — that's the first thing to internalize. It wraps a database-backed (Doctrine) message queue with a producer/consumer model. In a Laravel codebase you have two realistic entry points:
Minimal steps:
composer require strnoar/bqueuebundle
composer.json constraints first. Given the zero-star, zero-dependent footprint, expect an older Symfony (2.x/3.x) and pre-PHP 8 constraint — you will likely need --ignore-platform-reqs or a fork.AppKernel/bundles.php (Symfony) or publish a service provider that binds its dispatcher and consumer classes into Laravel's container.jobs/bqueue table with status, payload, priority, retry count).First use case: a small background job (resize an image, send an email) enqueued from a request handler, picked up by a long-running console command. Do this in isolation before trusting it with anything critical.
Producer/consumer via DB table. The core pattern is: a producer INSERTs a row, a worker polls for pending rows, marks them processing, runs your handler, then marks done or increments retries. Everything hinges on that table's state.
Laravel queue driver adapter. Write a class implementing Illuminate\Contracts\Queue\Queue that delegates push() to BQueue's dispatcher and pop() to its consumer's claim logic. Register it in config/queue.php under a custom connection. This keeps your jobs portable and lets you swap back to Redis/SQS later.
Supervision. The consumer is a blocking polling loop. Run it under Supervisor/systemd with --timeout, restart-on-exit, and log rotation. Do not run it from a web request.
Priority and retry. Model tries and backoff explicitly in your wrapper, mapping them onto whatever columns BQueue exposes (priority int, attempts int, available_at). Don't assume Laravel's semantics survive.
Integration tip: treat the queue table as a boundary. Producers and consumers should only touch it through the bundle's API, so a future migration to Laravel's native queue means rewriting one adapter, not every call site.
Idempotency wrapper. Because retries re-run the payload, wrap handlers in an idempotency guard (unique job key) — a DB-backed lock table works and matches the stack's existing style.
Horizon, no dispatch()->onQueue(), no native event hooks. Don't try to bolt Laravel's ShouldQueue contract straight onto it without the adapter in place.SELECT ... FOR UPDATE or SKIP LOCKED; without row-level locking you will double-process jobs when you scale to multiple workers.serialize(). Closures, resources, and non-serializable objects will fail silently or loudly depending on error handling. Prefer arrays and plain DTOs.processing forever. Add a reaper query that resets stale claims older than a threshold.SELECT status, attempts, priority, payload FROM ...) — it's your source of truth. Tail consumer output; the bundle's verbosity may be low, so add your own logging around the handler.How can I help you explore Laravel packages today?