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

Command Scheduler Bundle Laravel Package

jmose/command-scheduler-bundle

Symfony bundle for scheduling console commands with cron expressions. Define jobs in YAML, run due tasks via a single scheduler command, and track execution status and logs. A lightweight alternative to system cron for Symfony applications.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit

  • The headline is unchanged and decisive: jmose/command-scheduler-bundle is a Symfony bundle, not a Laravel package. v3.0.x adds Symfony 5 support; it does not add a service provider, facade, config publishing, or any awareness of Illuminate\Console\Scheduling\Schedule. The "Laravel" categorization in our tooling remains a tagging error.
  • Its model is still a single-minute tick: one system crontab entry polls a Doctrine-backed CronJob table, evaluates cron expressions, and spawns due commands as subprocesses. Architecturally analogous to Laravel's schedule:run, but independently implemented and Doctrine-coupled.
  • The differentiator still stands: database-driven, runtime-editable schedules plus an admin panel, versus Laravel's code-defined schedule(). Real capability — but reproducible in ~200 lines on dragonmantank/cron-expression without inheriting the dependency.

Integration feasibility

  • Into a Laravel codebase: still not feasible without a shim, and nothing in this release changes that. Booting a Symfony kernel inside Laravel, reconciling two Doctrine/DBAL stacks, duplicating container wiring, mounting a Symfony-only admin UI — cost/benefit still fails decisively.
  • Into a legacy Symfony app: feasibility has improved. Symfony 5 is now supported, so the target band widens from 3.4–4.x to 3.4–5.x. Still register-bundle, generate-schema, add-crontab-tick, optionally enable Sonata.
  • The realistic path for a Laravel shop remains pattern extraction, not package adoption.

Technical risk

  • Abandonment remains the dominant risk, but its character has changed. This is a single maintenance burst, not a revival: Symfony 5 support lands roughly one major version too late (Symfony 6 and 7 are unaddressed), and there is no evidence yet of a release cadence, CI matrix against current PHP, or a published security policy. Read it as "one contributor needed Symfony 5 in 2020," not "this project is back."
  • Closed risk — the transitive dependency conflict. v3.0.0 replaces abandoned mtdowling/cron-expression with dragonmantank/cron-expression. This removes the day-one Composer collision that previously made the package unusable in any modern app. Verify the pinned constraint: if it resolves to ^1.0|^2.0, it still conflicts with the ^3.0 line that current Laravel and Symfony apps carry, and the blocker merely moves.
  • New risk — mutable releases. v3.0.0 was pulled from Packagist "almost instantly" to correct a PHP constraint error. Yanking a published tag is a legitimate maintainer action, but it means tags in this repo are not treated as immutable and downstream installs can break without warning. Mitigation is non-negotiable: exact version pins, committed lockfiles, and an internal mirror or vendored fork.
  • Slightly reduced risk — Doctrine 3 path. Removal of deprecated merge() clears one ORM 3 migration obstacle. It does not constitute Doctrine 3 support; no such claim is made.
  • Admin panel remains a privileged execution surface. Unchanged by this release. Any web UI storing and executing arbitrary console commands is functionally a remote-execution console. Auth, CSRF, role separation, and network placement are tier-1 security controls.
  • Argument storage is still plaintext and visible to panel readers — a leak vector for tokens or IDs passed as arguments.
  • The capability demand signal (opportunity score 28.71) is unchanged and still argues for building, not adopting.

Key questions

  1. Do we have any Symfony runtime at all, or is this purely a Laravel estate? (If purely Laravel: stop here — this release does not move the answer.)
  2. Does the pinned dragonmantank/cron-expression constraint resolve to ^3.0, or does it still collide with our stack? This is now the only remaining install-time blocker to check.
  3. What PHP matrix does v3.0.1 actually pass against — 7.2 only, or 8.0+? Is there any CI at all?
  4. Is the admin panel intended for production, and behind what auth boundary and network ACL?
  5. What is our real requirement — code-defined schedules (Laravel native solves it) or runtime-editable schedules (needs a build)?
  6. Do we run multi-node? Is there a distributed lock, or will every node execute every job?
  7. What is the audit requirement for "who changed this schedule and when"?
  8. If we did adopt, who owns the fork when Symfony 6/7 and PHP 8.2+ become mandatory — and do we have a mirror to survive the next yanked tag?

Integration Approach

Stack fit

  • Laravel: poor fit — reject direct integration, unchanged. Laravel's scheduler already provides withoutOverlapping(), onOneServer(), runInBackground(), environments(), and Schedule::command()->cron(). For dynamic schedules, compose dragonmantank/cron-expression with an Eloquent model and a single schedule:run tick. Add spatie/laravel-schedule-monitor for missed-run alerting.
  • Symfony 5.x (legacy): now the best — and only — acceptable fit. v3.0.x is the first release that makes a Symfony 5 target viable without patching. This is the one deployment context where the bundle is cost-effective.

Migration path (Laravel, if capability is genuinely needed)

  1. Inventory every crontab line and existing schedule() entry; classify by frequency, runtime, criticality.
  2. Create scheduled_jobs (name, command signature, cron expression, timezone, args JSON, without_overlapping, on_one_server, enabled, last_run_at, last_exit_code, next_run_at).
  3. Register a single * * * * * php artisan schedule:run entry — the only OS-level cron we maintain.
  4. Evaluate due jobs each tick via CronExpression::isDue(), dispatch each as a queued job so a slow command cannot stall the tick.
  5. Enforce overlap protection at the job level (Cache::lock) and per-node deduplication.
  6. Ship an admin resource behind policy-gated authorization with an allowlist of dispatchable command signatures — never free-text command entry.
  7. Shadow-run for two weeks alongside the legacy crontab, diff execution counts, cut over, delete old entries.

Compatibility

  • Symfony bundle v3.0.x: Symfony 5.x, PHP >= 7.2 (v3.0.1 corrects a bad >= 7.1 constraint in 3.0.0), Doctrine ORM 2.x, optional Sonata Admin. Symfony 3.4/4.x support appears retained but should be confirmed against our constraint set before committing.
  • Laravel 9/10/11: incompatible — different container, console layer, and ORM. Unchanged by this release.
  • PHP 8.1+/Symfony 6/7: unsupported. Any move there returns us to fork-and-maintain; the modernization work in 3.0.0 buys us Symfony 5 only, not a forward path.

Sequencing

  • Week 0: decision gate — confirm no Symfony 5 runtime, close the evaluation, correct the "Laravel" tag in the package registry, and record the v3.0.x finding (Symfony 5 supported, dependency blocker cleared, framework mismatch stands).
  • Week 1: capability gap analysis (dynamic schedules: required vs. nice-to-have).
  • Weeks 2–3: build the Laravel-native equivalent only if the gap is confirmed.
  • Do not sequence work that assumes continued upstream maintenance; the release cadence has not been demonstrated.

Operational Impact

Maintenance

  • Still high relative to value, but materially better than the prior snapshot: we no longer inherit the mtdowling replacement work or the merge() deprecation. Symfony 5 support alone defers a fork by roughly one upgrade cycle.
  • The fork obligation is deferred, not removed. PHP 8.1+, Symfony 6, and Symfony 7 all remain unaddressed, and there is no signal that they are planned. Budget a fork at the next framework upgrade.
  • If forked, we inherit the obligation to publish internal releases. Register this as internal fork, not third-party dependency, if adopted anywhere.

Support

  • Community-only. No vendor, no SLA, no subscribable security advisory channel for this repo. Incident response for a scheduling outage is entirely internal, with no upstream backstop.
  • Bus factor remains effectively one maintainer. The v3.0.0 contributor credits (@spajxo, @pwbdod, @phansys, @balabis) suggest a slightly wider contributor pool than previously assessed — mildly positive, but these are one-off patches, not a maintainership transition.

Scaling

  • Unchanged. Per-tick cost scales linearly with stored jobs: one process per minute reads and cron-parses the full table. Fine at dozens, questionable at thousands.
  • Subprocess spawning per due job creates process-table pressure with no queue abstraction. A burst of jobs aligned to 0 * * * * produces a thundering herd at exactly the wrong moment.
  • Multi-node deployments still require explicit lock verification; a naive rollout double-executes every job.
  • The schedule table remains hot and write-heavy (last run, next run, exit codes) and needs its own retention policy.

Failure modes

  • Yanked or mutable release (new): v3.0.0 was removed from Packagist shortly after publication. Without exact pins, a lockfile, and a mirror, a routine composer update can install a version the maintainer has since retracted — or fail to resolve at all.
  • Missed tick: if the single cron entry or the app container is down, every job silently skips — no built-in dead-man's switch.
  • Overlap: long-running commands re-enter on the next tick absent overlap protection; the outcome is duplicated side effects, not an error.
  • Silent failure: non-zero exits are recorded but rarely surfaced; without alerting on last_exit_code and last_run_at staleness, failures persist unnoticed for days.
  • Log growth: per-job logs under var/log accumulate unbounded; disk-full takes down the whole application, not just scheduling.
  • Clock/timezone drift: PHP, DB, and system cron timezones diverging shifts schedules by hours with no error. Verify all three align.
  • Privilege escalation: an over-permissioned admin panel is an execution console; compromised credentials mean arbitrary command execution under the app user's context.
  • Exit-code/format change (new): standardizing command output on \DateTimeInterface::ATOM alters log and status-line formatting. If we feed these outputs into parsers or dashboards, validate them against v3.0.x before upgrading from 2.x.

Ramp-up

  • Symfony 5 engineer: ~1 day to install, configure, and ship a first scheduled job; ~3–5 days to harden (auth boundary, locking, alerting, log rotation, retention, mirror/pinning). Slightly faster than before — Symfony 5 is now a supported target rather than a patch exercise.
  • Laravel engineer: no meaningful ramp-up, because there is nothing to ramp up to. The effort transfers entirely to building the equivalent — ~3–5 engineering days including the admin surface and monitoring.
  • TPM recommendation: decline adoption for the Laravel estate; unchanged. The rationale has narrowed, and that is worth recording precisely: this release clears the dependency-conflict objection and extends framework support to Symfony 5. The decision now rests solely on framework mismatch, which is the one thing no version of this bundle can fix. Update the package registry to reflect "Symfony 5 compatible, dependency blocker resolved, not Laravel-compatible" so the finding is not re-litigated on stale grounds. Extract the DB-schedule-plus-admin requirement and satisfy it with Laravel's native scheduler and a policy-gated admin resource. The capability is worth building; this artifact is not worth inheriting.
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.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager