skywarth/chaotic-schedule
Generate random, realistic cron schedules and intervals in PHP and Laravel. Chaotic Schedule makes it easy to fake unpredictable schedule frequencies for tests, seeders, demos, and load simulations, with constraints for hours, days, and expressions.
Architecture fit
skywarth/chaotic-schedule is a thin extension point over Laravel's task scheduler: consumers call macros (randomDays, randomTimeSchedule) on the Schedule facade rather than adopting a new runtime, daemon, or storage layer. That keeps the blast radius small — no migrations, no queue driver assumptions, no new service to operate. For a TPM this is an attractive profile: the package is only in the critical path of when a job fires, not whether or how it executes, so a failure or rollback does not put application data at risk.
The v3.0.0 release is best characterized as a platform-floor release with a typed-API cleanup, not a feature release. The behavioural contract that matters most — seed determinism across (uniqueIdentifier, basisDate, periodType) — is explicitly preserved, so existing generated schedules do not drift on upgrade. That is the single most important line in the notes for planning purposes: no re-baselining of firing windows, no audit/reconciliation work required.
Integration feasibility Low effort, narrowly scoped, with one non-trivial caveat.
>=8.3 and Laravel >=13.x are already satisfied by the target application.RandomDateScheduleBasis::WEEK|MONTH|YEAR now resolve to enum cases, so the common path needs no code change.randomDays(...), and any use of the removed static helpers (getString(), getDayCount(), validate(), isValid(), getAll()), must be migrated to enum cases, cases(), tryFrom(), or ->periodString().InvalidScheduleBasisProvided in favour of a native TypeError is good design, but TypeError extends \Error, not \Exception. Any surrounding catch (\Exception $e) guard — typically added precisely to keep a bad config from taking down a scheduler run — now silently stops catching. The failure mode changes from "handled and logged" to "uncaught error." This must be treated as a required, code-searched migration item, not an optional tidy-up.Technical risk Overall: low-to-moderate, concentrated in two places.
PHP >=8.3, Laravel >=13.x) is the dominant adoption risk. If the estate is on Laravel 11/12 or PHP 8.2, v3.0.0 is simply unavailable, and the team stays on v2.x — which converts this into a support-lifecycle question rather than an integration question. Confirm Laravel 13's GA status and the maintainer's stated v2.x backport/security policy before committing either way.Key questions
catch (\Exception) blocks wrap randomDays / randomTimeSchedule calls today, and are they intended as invalid-input guards?TypeError acceptable to our error-handling standard, or do we want a thin local wrapper that restores an exception-typed boundary?Stack fit Good fit for any Laravel application already using the framework scheduler for jitter, load-spreading, or "poll at an unpredictable interval" patterns (webhook drainers, cache warmers, report fan-out, synthetic monitoring). It is a poor fit for anything requiring sub-minute precision, calendar-exact SLAs, or cryptographic unpredictability — the determinism feature exists for reproducibility, not secrecy.
Migration path Treat as a two-track decision:
randomDays(...) and for the five removed static helpers; (2) rewrite to enum cases / cases() / tryFrom() / ->periodString(); (3) widen or retype every guard around these macros from \Exception to \Throwable or \TypeError; (4) add a regression test asserting determinism for at least one representative schedule tuple.Because determinism is preserved, there is no data migration, no schedule re-baselining, and no coordination with downstream consumers — the upgrade is contained within the application repo.
Compatibility
Public macro names, parameter order, and behaviour are unchanged; the compatibility surface is the enum's static helper API and the exception type. The TypeError-extends-\Error distinction is the only place where "compiles fine, behaves differently" — call it out explicitly in the PR description so reviewers do not rubber-stamp it.
Sequencing
\Exception → \Throwable is backward-compatible on v2.x), then bump to v3.0.0 and convert to enums. This separates "behaviour-preserving hardening" from "breaking API change" and makes rollback surgical.Maintenance Ongoing cost is near-zero in steady state: no schema, no configuration surface, no state to reconcile. The recurring cost is version treadmill — v3.0.0 binding to Laravel 13 means the package's major releases are now coupled to framework majors, so expect this upgrade to recur annually. Budget a recurring small slot rather than treating it as one-off.
Support Support burden is concentrated on the team that owns scheduled jobs, not platform or DBA. The enum migration is a one-time developer task; after that, the failure surface is limited to misconfigured identifiers and basis dates. Document the accepted input types (enum cases only, no integers) in the internal runbook so future contributors do not reintroduce the deprecated call style.
Scaling
Scales with the scheduler, not with the package — cost is per-macro-invocation generation of dates, which is negligible relative to the jobs themselves. Watch only for pathological patterns where generation happens inside a high-frequency loop; the float-to-int conversion fix in randomTimeSchedule (PR #7) is a correctness improvement in exactly that area and is worth naming in the changelog review as a reason not to defer the upgrade indefinitely.
Failure modes
TypeError from an unguarded invalid period value — the headline risk. Manifests as a hard error during schedule registration, which in schedule:run context can prevent other scheduled tasks from registering depending on ordering. Widening catch blocks is the mitigation.Ramp-up Effectively nil for engineers already comfortable with Laravel's scheduler — the mental model is "a cron expression, but generated." The only conceptual speed bump is determinism: new team members assume randomness and are surprised that the same identifier and basis date reproduce the same runs, which is a feature for testability and a trap for anyone expecting fresh windows on redeploy. Put one paragraph on that in onboarding docs and one determinism test in the suite, and the ramp-up cost is measured in minutes rather than days.
How can I help you explore Laravel packages today?