m6web/daemon-bundle
Symfony bundle for turning console commands into long-running daemons. Extend the provided daemon command, implement your loop, and get signal handling, graceful shutdown, and simple process lifecycle management without boilerplate. Ideal for workers, queue consumers, and background jobs.
while loop, pcntl signal handling, a memory guard, and an event dispatcher hook. That is roughly a day of engineering to write and test. The package value is convention and precedent, not capability. A PM should price it as "a reference implementation we may vendor," not "a dependency we adopt." New in v9.0.0: the maintainer replaced the bundle's own handleSignal function with a ConsoleCommandListener class because it collided with the new handleSignal added in Symfony 7.3. That is precisely the subsystem a team would copy if they vendored the pattern — and it just broke against a framework minor release. Budget the port as "copy the shape, own the signal handling," and expect to revisit it whenever the framework moves.config/ publish path for Laravel. For a Laravel codebase the decision shifts from "install it" to "port the pattern" — which reframes the whole build-vs-buy call. The v9.0.0 breakage is Symfony-specific and does not touch Laravel, but it does illustrate why a port should be written against Laravel's own signal handling rather than transcribed from this bundle's internals.Consider it when all of the following hold:
^9.0 on Symfony 7.3+; treat v8.x as unsupported on 7.3 and later.Look elsewhere when:
queue:work with Horizon, or a scheduled command at everyMinute/everyFiveSeconds. Adding a Symfony bundle to Laravel is a net-new adapter layer for a commodity feature.Executives: This is a small, MIT-licensed utility that lets PHP run a long-lived background command with clean startup, shutdown, and a memory cap. It is not a queue, not a scheduler, and not infrastructure — it's a coding convention plus about a hundred lines of loop and signal handling. Cost to adopt is low; cost to own is a supervised process, which we'd pay regardless of which library we pick. No license cost, no strategic lock-in. Vendor risk is real but smaller than it looked: still ~59 stars and no downstream dependents, effectively one maintainer — but the just-shipped v9.0.0 shows that maintainer responding quickly and correctly to a breaking framework change (Symfony 7.3 changed its signal handling and this bundle's approach collided with it). That is a good sign, and it is also a reminder that this dependency will require periodic version upkeep rather than "install once." Recommendation: don't budget it as a platform investment. Treat it as a tactical pattern — either port the loop into our own base command (preferred if we're on Laravel) or adopt it in a single bounded service we can replace in a day, pinned to ^9.0. The decision it should unblock is "do we need a broker, or is a poller enough for this feature?" — and for the specific use cases on the table, a poller is enough.
Engineering: The package is a Symfony bundle providing a DaemonCommand base class: loop with per-iteration events, signal handling for graceful shutdown, a memory-limit check, and a --run-once mode. It does not supervise, restart, distribute, retry, or instrument. v9.0.0 is a breaking change: the bundle's internal handleSignal function is removed and replaced by a ConsoleCommandListener class, because the old function conflicted with the new handleSignal introduced in Symfony 7.3. Upgrade to v9 if you're on 7.3+; do not mix v8.x with Symfony 7.3. For Laravel, expect to port the pattern rather than install the bundle — one class, one console command, one Supervisor program — and write the signal handling against Laravel's own facilities so this specific Symfony-internal collision can't reach us. Isolate it behind an internal interface so replacement with Messenger, Horizon, or Swoole is a config change, not a refactor. Budget half a day to read the source before committing; the value is in the shutdown and memory-guard details, which are the parts teams usually get wrong on the first attempt — and, as v9.0.0 demonstrates, the parts most exposed to framework churn.
How can I help you explore Laravel packages today?