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

Cron Bundle Laravel Package

psf1/cron-bundle

psf1/cron-bundle is a Symfony bundle for defining, scheduling, and running cron jobs from your application. It helps manage recurring tasks in one place, reducing reliance on system crontabs and making scheduled work easier to configure and maintain.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Release delta (1.0.2). Two changes: dependency injection support in cron jobs, and a README update. This is a feature addition shipped in a patch version, which is itself a signal — adding capability under 1.0.x suggests loose versioning discipline upstream, so pinning an exact commit rather than a constraint range remains mandatory. The DI feature is the only item with engineering consequence, and it cuts in two directions:

  • Positive: jobs become container-resolved classes rather than hardcoded closures, which improves testability (constructor-injected collaborators can be mocked) and makes job definitions more declarative.
  • Negative: it implies a container abstraction dependency. If jobs are resolved from Symfony's DI container or the bundle's compiler pass, framework coupling deepens and the Laravel fit degrades further. If resolution is via a PSR-11 ContainerInterface, the coupling is portable and this is a genuine improvement.

We cannot distinguish between those two from the release notes, and the distinction determines whether this release reduces or increases migration cost.

Architecture fit. The package name and namespace (CronBundle) strongly indicate a Symfony bundle, not a Laravel package. That distinction matters: Symfony bundles rely on Bundle classes, DI container extension definitions, and typically Doctrine ORM entities and migrations — none of which Laravel's service container, Eloquent, or migration runner consume natively. The 1.0.2 DI change reinforces the bundle framing rather than softening it. If the consuming stack is Laravel (as the framing suggests), there is no architectural fit out of the box; the package would need a compatibility shim or a reimplementation of its core logic. If the consuming stack is actually Symfony, the fit is plausible but still unverified — we have no confirmation of supported Symfony major versions, and the base release predates Symfony 6.1+ and 7.x.

Functional scope. Per the description, the package manages cron schedules dynamically, dispatching either HTTP requests or console commands from a data-driven schedule store. Architecturally that implies: a persistent schedule table, a single "tick" entry point (likely one system crontab line calling a console command), a dispatcher, and some execution/logging record. Post-1.0.2, add a job-resolution layer between dispatcher and execution. That is a modest, well-understood problem domain — which cuts both ways: it is valuable if it's already tested and robust, and it is entirely reproducible in-house if it isn't.

Integration feasibility. Unknown-to-low on the evidence available. There are zero dependents and zero stars, meaning no public reference implementations, no third-party integration reports, and no ecosystem signal that the composer constraints resolve cleanly against current frameworks. A single 1.0.2 release is not evidence of active maintenance — one commit after a multi-year gap is the classic signature of a package that receives occasional drive-by attention, not stewardship. We still cannot confirm from the repository metadata alone whether the package ships tests, CI, static analysis, or a declared license — all of which are gating checks before any code enters our dependency graph.

Technical risk. High, concentrated in five areas:

  1. Dependency rot. The base release is frozen at 2022-02-01 and likely targets PHP 7.4/8.0 and Symfony 5.x. Installing it into a modern runtime may require constraint overrides, which is a maintenance liability from day one.
  2. Single-maintainer / bus factor 1. No dependents means no downstream pressure to keep it patched. One patch release does not change the structural incentive.
  3. Attack surface. A package whose purpose is to trigger outbound requests and execute console commands on a schedule is, if misconfigured, a remote command execution vector. DI support widens this slightly: container-resolved job classes can now pull arbitrary services and configuration into an execution path. Any HTTP endpoint it exposes to register or fire jobs requires authentication, authorization, and input validation review before we would run it anywhere.
  4. Correctness under concurrency. Overlapping ticks, duplicate dispatch across multiple app nodes, and DST/timezone handling are the classic failure modes of homegrown schedulers; we have no evidence these are addressed.
  5. Container resolution failures. New with 1.0.2: a job class whose constructor dependencies cannot be satisfied in the tick process (CLI entry point, no HTTP request scope, possibly no session or auth context) will fail at resolution time. Whether that fails one job or aborts the entire tick is unverified and is now a first-order question.

Key questions for the maintainer or a code spike.

  • Does it support dependency injection for job definitions? Partially answered by 1.0.2 — resolution mechanism still unknown.
  • Does job resolution use PSR-11 ContainerInterface, Symfony's ContainerInterface/service locator, or a bespoke resolver? This determines portability.
  • Are constructor-injected dependencies resolved lazily at fire time or eagerly at registration? Eager resolution can break the tick when any one job's dependencies are unavailable.
  • Is a failed resolution isolated to the single job, or does it abort the tick for all jobs?
  • Was the DI change additive or did it alter the job interface / registration signature? Is 1.0.2 a breaking change mislabeled as a patch?
  • What is the license, and is the repository actively accepting issues/PRs?
  • What PHP and Symfony version ranges are declared, and do they resolve against our target runtime?
  • Does it persist schedules via Doctrine ORM specifically? If so, an Eloquent-based stack inherits a Doctrine dependency or a rewrite of the persistence layer.
  • How is the tick entry point secured — CLI-only, or is there an HTTP trigger route?
  • What concurrency controls exist (locking, mutex, single-flight guarantees) for multi-node deployments?
  • Is there test coverage, and does it exercise command execution, DI resolution, and failure paths?
  • How are job failures surfaced — logs, retries, alerting hooks?
  • What is the schedule table's retention/growth policy?

Integration Approach

Stack fit. The first decision is a factual one: confirm whether the target application is Laravel or Symfony. If Symfony, proceed to a dependency-resolution spike and specifically validate that DI-resolved jobs behave correctly under the bundle's container in a CLI context. If Laravel, treat this package as reference material rather than a dependency — read its design, then implement the equivalent on Laravel's native scheduler plus a database-backed schedule registry. Laravel's Schedule facade, schedule:run invoked once per minute from cron, withoutOverlapping(), and the framework's own container resolution for job classes already cover the majority of what this package now advertises — 1.0.2 narrows the gap between the package and native Laravel capability rather than widening it. In Laravel, "inject dependencies into a scheduled job" is app()->make(JobClass::class), not a feature.

Migration path (if adoption is pursued).

  1. Fork the repository into our organization and pin a specific commit — never track a floating branch from an unmaintained upstream. Pin at 1.0.2 or later, not the 2022 baseline, since the DI change may alter job registration signatures.
  2. Add it as a VCS or path repository in composer.json, isolated behind an internal interface (e.g., a JobScheduler contract) so the underlying implementation is swappable.
  3. Do not allow the package's entities, models, or container abstractions to leak into application code; expose only our own DTOs and service methods. This matters more post-1.0.2, where container coupling is newly in play.
  4. Vendor the code with a documented upgrade path so a future replacement requires touching one adapter, not the whole codebase.

Compatibility work. Expect to raise PHP and framework constraints in the fork and run the full test suite (if any exists) plus our own integration tests against the target runtime. Add explicit coverage for DI: resolve every registered job class inside the actual tick process and assert clean failure isolation. Budget for a Doctrine-to-Eloquent bridge only if the persistence layer is genuinely Doctrine-bound and we are on Laravel — in which case the bridge is likely more work than a rewrite.

Sequencing.

  1. Week 1 — Feasibility spike. Clone at 1.0.2, diff against the prior release to establish whether the DI change is additive or breaking, read the resolver, resolve dependencies in a scratch container, document license and version constraints. Kill or continue.
  2. Week 2 — Security and correctness review. Specifically: trigger endpoint auth, command injection paths, container-resolution scope (can a job reach services it shouldn't?), locking behavior, failure handling.
  3. Week 3 — Build-vs-adopt decision. Compare against (a) fork-and-harden, (b) reimplement on native scheduler, (c) a maintained alternative. Weight by total cost of ownership, not feature count.
  4. Week 4+ — Pilot. Single non-critical scheduled job in a staging environment, with run-history verification and at least one job using constructor injection to exercise 1.0.2, before any production traffic.
  5. Production rollout only after alerting on missed and failed runs is confirmed working.

Given the evidence, my default recommendation remains (b) reimplement: the domain is small, the native primitives are strong, and one patch release does not convert a zero-adoption, years-stale package into a maintained dependency. The 1.0.2 DI feature marginally strengthens the case — it demonstrates that the package's differentiating capability is something the native framework already provides, so we would be adopting a maintenance burden to obtain behavior we get for free.

Operational Impact

Maintenance. The upstream is effectively dormant. A single 1.0.2 release is a data point, not a trend; it does not establish a patch cadence, an issue-response SLA, or a security disclosure process. Adopting it means adopting the maintenance burden: security patches for a package nobody else is watching, dependency bumps against future PHP/Symfony/Laravel releases, and framework API drift with no upstream fixes. Every future framework upgrade becomes a fork-merge exercise, now including the job-resolution layer. This cost is ongoing and should be staffed, not assumed away.

Support. No community, no dependents, no public issue history to mine for known problems. One recent README update is not documentation of runtime semantics. Internal knowledge will concentrate in whoever performs the spike — a bus factor of one inside our own team on top of the upstream bus factor of one. Mitigate with written runbooks and at least two engineers touching the code during the pilot.

Scaling.

  • Resolution floor. Cron granularity is one minute; the package cannot schedule sub-minute work regardless of implementation.
  • Horizontal scale. If the app runs multiple nodes, each node's cron will tick the scheduler unless the package implements leader election or a lock. Duplicate dispatch is the most likely scaling failure and must be tested explicitly with ≥2 instances.
  • Database contention. A schedule table polled every minute is low-volume and unlikely to be a bottleneck, but execution-history tables grow unbounded without a retention policy.
  • Throughput. Long-running dispatched commands occupy the tick process; without per-job timeouts and concurrency limits, one slow job delays everything behind it.
  • Resolution cost. Post-1.0.2, every tick constructs job objects with their dependency graphs. If the resolver builds these eagerly for all registered jobs rather than lazily for due jobs only, per-tick overhead scales with total schedule count, not due-job count. Worth measuring at realistic table sizes.

Failure modes to instrument from day one.

  • Silent non-execution — the tick command itself fails or isn't installed; nothing runs and nothing alerts. Alert on "no tick recorded in N minutes."
  • Unresolvable dependency — new in 1.0.2. A job class whose constructor dependencies cannot be satisfied in CLI scope. Determine blast radius: single job or whole tick. This is the highest-priority new test.
  • Duplicate execution — multi-node ticks firing the same job twice. Requires idempotency in downstream jobs and a lock in the scheduler.
  • Runaway/hung jobs — no timeout, no kill, backlog accumulates.
  • Timezone and DST drift — schedules firing twice or not at all around transitions; require explicit UTC handling.
  • Unauthorized trigger — if an HTTP registration or fire endpoint exists and is exposed, this is a command-execution path. Treat as a security control, not a config detail. DI resolution widens the set of services reachable from that path.
  • Dependency breakage on upgrade — the package's constraints block a framework upgrade mid-project.

Ramp-up. The codebase is likely small enough to read end-to-end in a day, so raw comprehension cost is low. The real ramp-up cost is the absence of documentation: expected behavior for overlapping runs, timezone semantics, failure retry policy, and now dependency-resolution scope and failure isolation will have to be reverse-engineered from source and captured in an internal runbook. Allocate roughly one engineer-week for the spike, review, and documentation before committing to a pilot, and treat "documented behavior" as a deliverable of that week — if the team cannot articulate the failure semantics clearly by the end of it, that is itself the signal to reimplement. The 1.0.2 README update should not be counted toward that deliverable until reviewed; a diff against the prior README is part of the Week 1 spike.

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.
unabomber/timezone
delatbabel/contacts
astritzeqiri/g-recaptcha
kevinongko/laravel-genode
developeruz/laravel-analytics
robbiep/afterthedeadline
frankkessler/incontact-laravel-oauth2-rest
jlxh/laravel-userlog
davidmgilo/timetables
qylinfly/role-permission
reflect-digital/conduit
takashato/laravel-vietqr
aitor24/laralang
kraenzle-ritter/entity-relations
dindigital/din-image
pomirleanu/image-colors
sawmainek/laravel-api-generator
delatbabel/jsonresponses
mouhamedfd/permissions-generator
eduplus/qr