Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Console Command Scheduler Bundle Laravel Package

bytespin/console-command-scheduler-bundle

ByteSpin Console Command Scheduler is a Symfony 6.3+ bundle for scheduling console commands via Messenger Scheduler, logging execution time, duration and return codes to database and log files, with an EasyAdmin interface and extendable email notifications.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Framework mismatch is the first finding. The brief frames this as a "Laravel/PHP package." It is not. bytespin/console-command-scheduler-bundle is a Symfony bundle (PHP 8.2+, Symfony 6.3+, Doctrine ORM, EasyAdmin, Messenger/Scheduler). If the target application is Laravel, this is a non-starter: there is zero reusable surface. The scheduling model (RecurringMessage::every / ::cron), the service container wiring, the entity mapping, and the admin controllers are all Symfony idioms. A Laravel port would be a from-scratch build against Schedule::command(), so this package should be treated purely as a design reference. The assessment below assumes a Symfony estate; if that assumption is wrong, stop here.

Architecture fit (Symfony). The bundle is a thin persistence-and-admin facade over Symfony's native Scheduler and Messenger components. That is the right shape: it does not invent a scheduler, it stores RecurringMessage definitions in Doctrine and exposes CRUD. Conceptually clean, single responsibility. Two architectural frictions remain:

  • Vendor-mapped entities. The Scheduler and SchedulerLog entities live in vendor/bytespin/.../src/Entity and are mapped directly into the host application's entity manager. This couples your Doctrine metadata, your schema, and your migrations to a third-party vendor path. It also forces a project-wide config change: auto_mapping: true must be disabled and every entity in the app remapped. In a multi-entity-manager application that is a nontrivial blast radius.
  • Hard dependency on EasyAdmin for the UI, with no DashboardController shipped. The README implies the admin surface is optional in principle (core scheduling is the events + Messenger path), but this is unverified and should be spiked before committing.

Integration feasibility: medium-to-hard. There is no Symfony Flex recipe. Installation is a manual checklist: composer require, manual registration in config/bundles.php, run bytespin:configure-console-command-scheduler, hand-verify doctrine.yaml mappings, then doctrine:schema:update --force. Note a documentation defect worth catching in a 30-second Packagist check: the README's install command says bytespin/console-commande-scheduler-bundle (with an "e", French spelling) while the repository is console-command-scheduler-bundle. Confirm the actual package name before writing it into a build.

Technical risk factors:

  • Bus factor 1, 0 stars, 0 dependents, self-declared beta. Upstream support is effectively one person responding to GitHub issues. Plan for self-support.
  • No shipped migrations. Schema is driven by doctrine:schema:update --force, the README explicitly warns you to run it on updates, and it even self-contradicts on which versions changed the schema ("1.0.13 requires schema update" vs. "last version that includes schema modifications is 1.1.0"). Using schema:update --force in a controlled production pipeline is a policy violation in most shops.
  • Scheduler component maturity. Symfony Scheduler was experimental in 6.3. Verify 7.x and Doctrine ORM 3 support — the README only claims 6.3+ and says nothing about 7.

Credible positives. The 2.1 reliability work is genuinely above average for a solo beta bundle and signals the author has been burned in production: class-level validation that rejects a cron expression typed into the interval field, per-entry fault isolation with a SchedulerEntryFaultedEvent, an invalid badge in the admin list, and a bytespin:scheduler:lint command that exits non-zero. That last one is the single most valuable feature here — it turns a runtime class of failure into a CI gate.

Key questions before adoption: Is the estate Symfony 6.3+/7.x, or Laravel? Does the app already run Messenger with a persistent worker and a transport? Does it already use EasyAdmin, and does core scheduling work headless if we don't want it? Can we replace schema:update --force with generated migrations against the vendor entities, and will those entities survive an upgrade? Is the maintainer responsive, and what is the stated BC policy for a 1.x beta?

Integration Approach

Stack fit gate. Proceed only if: PHP 8.2+, Symfony 6.3+ (validate 7.x in a spike), Doctrine ORM with a single primary entity manager (or willingness to remap all entities), Messenger configured with a transport, and supervisor/systemd available for a long-running consumer. If the app is API-only and has no EasyAdmin, budget a spike to confirm the admin layer is detachable before assuming it is.

Migration path by starting point:

  • Greenfield scheduling — clean adoption; use the bundle rather than hand-rolling YAML schedules.
  • Existing crontab or hand-rolled Symfony Scheduler config — dual-run for one or two cycles. Keep cron entries active while the bundle runs in parallel, diff execution timings and return codes, then cut over per command.
  • Laravel Schedule::command() — do not attempt a port. Re-baseline as a Symfony-native scheduler or stay on Laravel's scheduler.

Sequencing:

  1. Spike in a branch — install, register, map, run bytespin:configure-console-command-scheduler, schedule one trivial command, run messenger:consume scheduler_scheduler -vv, confirm the log row and admin view. This validates the entire wiring in under a day.
  2. Pin an exact version in composer.json and record it. Beta software should never float.
  3. Own the schema. Generate Doctrine migrations from the bundle entities into migrations/, review them, and commit. Add a CI gate that fails if doctrine:schema:validate detects drift. Explicitly ban schema:update --force outside local/CI.
  4. Wire the config file (bytespin_console_command_scheduler.yaml), including an explicit process_only_last_missed_run decision — do not inherit a default by accident.
  5. Provision the worker under supervisor with restart-on-failure, plus per-queue workers if you route long-running tasks off the default scheduler queue.
  6. Seed 2–3 low-risk commands, verify durations and return codes in the log view.
  7. Gates and monitoring — bytespin:scheduler:lint in CI and in the deploy pipeline; a SchedulerEntryFaultedEvent listener that pages your on-call channel.
  8. Admin menu — add the submenu to your existing DashboardController.
  9. Tags last — optional, off by default, and requires a host-app Tag entity plus resolve_target_entities. Treat as a later phase; it adds schema surface for cosmetics.

Compatibility caveats. No Flex recipe means no auto-generated config and no guaranteed upgrade path — treat every composer update as a manual schema-review event. Version 1.1.0 was the last schema-changing release, so pinning at or above that avoids cross-major schema jumps, but verify against the changelog each bump.

Vendor strategy. Given the vendor-mapped entities and absent migrations, evaluate forking into an internal namespace or vendoring a pinned copy so schema changes enter your repo as reviewable diffs rather than as vendor/ surprises.

Operational Impact

Maintenance. Ongoing cost is dominated by the missing recipe. Every upgrade is a manual checklist item ("do not forget to update the database schema"), which is exactly the kind of instruction that becomes an incident when it is forgotten. Mitigate with a written runbook entry, the schema-drift CI gate, and a policy that bundle upgrades ship in the same PR as their generated migration. Assume one to two days of engineering per year simply tracking upstream, plus the initial integration.

Support. Upstream support is a single maintainer's GitHub issue queue with no SLA. Operationally, this package must have a named internal owner. Treat bug reports as something you file as a courtesy, not as a dependency in your incident plan.

Scaling. Three separate vectors:

  • Worker throughput — a single messenger:consume scheduler_scheduler is a serial bottleneck. The per-task messenger queue field is the correct escape hatch: route slow ETL-ish commands to a dedicated queue so they cannot block the default scheduler queue. Use it deliberately, not as a post-incident patch.
  • Log table growth — every execution writes a row with return code, timestamp, and duration. There is no retention policy in the docs. Enable No DB Log on chatty high-frequency commands and schedule a pruning job on SchedulerLog from day one.
  • Schedule table size — trivially small; not a concern.

Failure modes, ranked:

  1. Silent total outage — worker down. If messenger:consume is not running, nothing executes and nothing complains. This is the primary operational risk. Mitigate with an external heartbeat: alert if no SchedulerLog row has been written within N minutes, where N is well below your most frequent schedule's interval.
  2. Entry-level faults. Pre-2.1 an invalid entry could take down the whole schedule build. 2.1+ isolates it and emits SchedulerEntryFaultedEvent, but the entry still silently stops running. The lint command plus the fault listener together close this; either one alone does not.
  3. Missed-run semantics. Default is at most one catch-up per task after downtime, which is a behavior change from replay-everything. Decide explicitly and write it into the runbook, because "why did my batch job only run once after the outage" is a predictable page.
  4. Schema drift after an upgrade. New bundle code queried against an old schema, or vice versa. Covered by the migrations gate above.
  5. Entity-manager confusion. getManagerForClass() will misbehave if auto_mapping: true returns or if entities are mapped to multiple managers. Lock this with a config test.
  6. EasyAdmin coupling. A breaking EasyAdmin major could take out the admin UI while the scheduler keeps running. Acceptable — UI loss is not execution loss — but it should be a known, tolerated degradation rather than a surprise.

Ramp-up. Operators ramp fast: the EasyAdmin screens are self-describing (disabled, command, arguments, type, frequency, from/until, log file, no-DB-log, queue), and the log viewer needs no training. Engineers need moderate ramp: the wiring is invisible in code and lives entirely in bundles.php, doctrine.yaml, the config YAML, and a supervisor unit. Estimate half a day for a Symfony-fluent developer to reach a working demo, and one to two additional days to make it production-safe (migrations, worker supervision, heartbeat alerting, CI lint, fault listener).

Exit cost: moderate and bounded. Everything underneath — Messenger, Scheduler, Doctrine — is standard Symfony. The bundle's persistent footprint is two tables and a config file. Replacing it with native Symfony Scheduler YAML plus a small custom admin is a realistic escape hatch, which is the strongest argument for adopting it: the lock-in is shallow even if the vendor relationship fails.

Recommendation. Adopt only in a Symfony 6.3+/7.x application that already runs Messenger with a supervised worker and already uses EasyAdmin. Enforce a pinned version, owned migrations, CI lint, a fault-event listener, and a worker heartbeat. Do not adopt it in a Laravel application, and do not adopt it without the heartbeat — the silent-worker-down failure mode is the one that will burn you.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
alphabalex/messaging-made-easy
rawphp/warp
shootkiran/merobug
narakode/fineauth
numencode/wn-syncops-plugin
ibnnajjaar/mib-global-pay
ably/pubsub-server
mstfkhazaal/defender
mfonte/base62x
karnoweb/metapilot
tobya/bcsapiwrapper
swalker2/cpanel
vish4395/laravel-translation-manager
morningtrain/economic
teksite/systeminfo-laravel
atomcms/voting
run6/weather
siokas/laravelembeddirectives
adamlien/pkuuids
gilsonsouza/lara-doc-generator