serendipity_hq/commands-queues-bundle
Symfony bundle for queuing and running console commands as background jobs. It helps dispatch commands to a queue, process them asynchronously, and manage workers, making long-running PHP tasks easier to offload without blocking web requests and keep responses fast, with a simple, framework-friendly...
This is a Symfony bundle, not a Laravel package — the first decision is whether it belongs in your stack at all. In Laravel you already have php artisan queue:work, dispatch(), and Artisan::queue(); this bundle exists to give a Symfony app the same "enqueue a console command, run it in a background worker" capability, persisted through Doctrine. If you're a Laravel dev, the realistic use cases are: (a) you maintain/consult on a Symfony app and need to wire this in, or (b) you're reading it to borrow the design for a custom "command queue" table in Laravel.
Minimal steps in a Symfony app:
composer require serendipity_hq/commands-queues-bundleconfig/bundles.php (or AppKernel::registerBundles() on older Symfony).bin/console doctrine:schema:update --force (or generate/run a migration) to create the queue table backed by the bundle's Doctrine entities.config/packages/ — the bundle exposes settings for the queue table/entity and processing behavior; publish or hand-write the YAML keyed to the bundle alias.bin/console list | grep -i queue and dry-run it against a trivial command (e.g. enqueue cache:clear).Where to look first: the Doctrine entity for queued commands (the table is the whole state machine), the worker/processor console command, and the service you call to enqueue. First real use case: enqueue one of your existing, slow console commands (report generation, imports, cache warmers) instead of running it inline, then run the worker under supervisor/systemd and watch rows move from queued → running → done/failed.
Enqueue from app code, process out-of-band. Treat enqueueing like Laravel's dispatch(): your controller/service writes a "queued command" row (command name + arguments + priority), returns immediately, and a separate long-running worker consumes it. Keep enqueueing cheap and never run heavy work in the request cycle.
Worker supervision. Run the worker as a daemon (supervisor/systemd), not from a request. In Laravel terms this is queue:work; here you're shelling out Symfony console commands per row, so each "job" is a full process — expect higher overhead per item than a Laravel job.
Status lifecycle as the source of truth. Model your monitoring off the row status/state column(s): queued, in-progress, completed, failed. This is what makes the bundle usable — you can query the table for stuck or failed items, exactly like inspecting failed_jobs in Laravel, and build a small admin view over it.
Prioritize and batch. Use the priority field (if exposed) to push critical commands ahead of bulk work, and enqueue in loops for batch imports — but throttle enqueue rate so the table doesn't balloon and the worker doesn't starve.
Scheduling the enqueue side. Cron/Symfony Scheduler should enqueue, while the worker process drains. Keep these two concerns separate so a missed cron doesn't stall the worker and vice versa.
Porting the pattern to Laravel. If you like the model but live in Laravel, you don't need the bundle — implement a queued_commands table with command, payload, status, priority, attempts, output, timestamps, enqueue via Artisan::queue($command, $args) on the database driver, or use Bus::batch() for grouped work. Use Artisan::call() inside a job only when you specifically need console-command semantics (output capture, exit codes) rather than a plain job class.
SELECT ... FOR UPDATE/SKIP LOCKED semantics or a claimed-by column yourself.attempts counter and requeue logic in a wrapper, and always store stderr/exit code for debugging.bin/console cache:clear; stale config is the usual cause of "my new setting is ignored."How can I help you explore Laravel packages today?