Weave Code
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

Cadence Laravel Package

directorytree/cadence

Cadence adds model-based scheduling to Laravel. Attach one or more cron or RRULE schedules to any Eloquent model, track due runs, and dispatch events when schedules trigger. Driver-based design supports cron, php-rrule, Recurr, or custom drivers.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture Fit

  • Strengths:

    • Model-aware scheduling: Perfect for Laravel applications where scheduling is tied to business entities (e.g., User, Invoice, Report). The polymorphic schedulable_type/schedulable_id design ensures clean, scalable integration.
    • Driver diversity: Supports Cron (simple) and RRULE (complex) via two libraries (php-rrule/Recurr), catering to both basic and advanced recurrence needs. Custom drivers allow domain-specific extensions (e.g., fiscal-year scheduling).
    • Event-driven execution: ScheduleTriggered events enable decoupled, observable workflows, aligning with Laravel’s ecosystem (e.g., queue jobs, notifications). The SerializesModels trait simplifies event payloads.
    • Timezone support: Critical for global apps, with explicit Carbon timezone handling. Avoids common pitfalls of naive UTC-based scheduling.
    • Precomputed next_run_at: Optimizes query performance for due schedules, reducing runtime overhead compared to runtime calculation.
  • Fit for:

    • Dynamic workflows: Ideal for apps where schedules are data-driven (e.g., "generate this report every Monday at 9 AM ET for this customer").
    • Recurrence complexity: RRULE support handles edge cases (e.g., "every 3rd Friday of the quarter") that Cron cannot.
    • Event-driven architectures: Integrates seamlessly with Laravel’s event system, queues, and observers.
    • Laravel 11+: Leverages modern PHP/Laravel features (e.g., enums, first-class attributes) without legacy baggage.
  • Misalignment:

    • Not for serverless: Requires a persistent Laravel instance to run schedules:run. Poor fit for AWS Lambda or cron-less architectures.
    • No built-in retries: Relies on Laravel’s queue system for retries; lacks native exponential backoff or dead-letter queues.
    • Single-region by default: Timezone logic assumes a single app instance. Multi-region deployments may need custom logic to avoid race conditions.

Integration Feasibility

  • Stack Compatibility:

    • Laravel 11+: Mandatory upgrade for PHP 8.2+ features (e.g., read-only properties, enums). Low risk if already on Laravel 10+.
    • Dependencies:
      • Core: Minimal (directorytree/cadence).
      • Drivers: Optional but required:
        • dragonmantank/cron-expression (Cron): Stable, widely used.
        • rlanvin/php-rrule or simshaun/recurr (RRULE): Choose one; Recurr is more feature-rich but less maintained.
      • Risk: Driver conflicts (e.g., carbon/carbon versions) may require composer overrides.
    • Database: Adds a schedules table with polymorphic relations. Migration is straightforward but requires downtime if using zero-downtime deployments.
  • Migration Path:

    1. Upgrade: Laravel 11 + PHP 8.2 (if not already).
    2. Install: Composer packages + publish migrations.
    3. Model Integration: Add HasSchedules trait to target models (e.g., Report, User).
    4. Event Listeners: Register ScheduleTriggered handlers (e.g., queue jobs, send emails).
    5. Scheduler Setup: Add schedules:run to routes/console.php and configure Laravel’s scheduler (e.g., everyMinute()).
    6. Testing: Validate edge cases (timezones, recurrence rules, concurrent runs).
  • Key Questions:

    • Driver choice: Will php-rrule or Recurr suffice, or do we need custom logic?
    • Timezone strategy: How will we handle multi-region deployments (e.g., sync next_run_at across regions)?
    • Error handling: How will failed schedules be retried or alerted? (Requires custom event listeners.)
    • Performance: What’s the expected scale (e.g., 10K vs. 1M schedules)? May need indexing on next_run_at.

Technical Risk

  • Driver Limitations:

    • Cron: Limited to 5 fields; no support for complex exceptions (e.g., "every Monday except holidays").
    • RRULE: Library quirks (e.g., php-rrule’s BYSETPOS vs. Recurr’s implementation). Test edge cases like:
      • DTSTART in the past.
      • UNTIL or COUNT with timezone offsets.
      • Leap seconds/years.
    • Custom drivers: Requires deep understanding of resolveNextOccurrence() logic.
  • Race Conditions:

    • next_run_at updates: If schedules:run executes concurrently, two instances might process the same schedule. Mitigate with:
      • Database transactions + FOR UPDATE locks.
      • Laravel’s withoutOverlapping() (already included in the example).
    • Timezone drift: If the app spans timezones, next_run_at may become stale. Solution: Use UTC internally, convert to local time only for display.
  • Observability:

    • No built-in logging: Must instrument ScheduleTriggered events or add custom logging to track runs/errors.
    • Metrics: Lack of native support for tracking schedule success/failure rates (consider Prometheus client integration).
  • Failure Modes:

    • Stale schedules: If schedules:run fails or is misconfigured, schedules may not fire. Monitor with:
      • Laravel Horizon for queue jobs.
      • External alerts (e.g., "no ScheduleTriggered events in 5 minutes").
    • Database bloat: Unbounded schedules table growth. Consider archiving old schedules (e.g., last_run_at > 2 years ago).

Integration Approach

Stack Fit

  • Laravel Ecosystem:

    • Native integration: Works seamlessly with Eloquent, Events, Queues, and Scheduler.
    • Testing: Use Laravel’s testing tools (e.g., Schedule::fake()) to mock schedules in unit/feature tests.
    • Deployment: No additional infrastructure needed beyond Laravel’s scheduler (e.g., Supervisor, Kubernetes CronJob).
  • Compatibility:

    • PHP 8.2+: Leverages modern features (e.g., enums, constructor property promotion). Avoids legacy array_merge hacks.
    • Laravel 11: Uses first-class attributes and improved DI. Downgrades may require adapter layers.
    • Database: Supports MySQL, PostgreSQL, SQLite (via Eloquent). No vendor-specific SQL.
  • Extensions:

    • Custom drivers: Extend DirectoryTree\Cadence\Drivers\Schedule for domain-specific logic (e.g., "run every fiscal quarter").
    • Event listeners: Add logic to ScheduleTriggered (e.g., Slack alerts, analytics).
    • Admin UI: Integrate with Laravel Nova or Filament for managing schedules via a dashboard.

Migration Path

  1. Preparation:

    • Upgrade: Migrate to Laravel 11 + PHP 8.2 if needed.
    • Backup: Database and existing cron jobs.
    • Audit: Identify models needing schedules (e.g., Report, Subscription).
  2. Installation:

    composer require directorytree/cadence dragonmantank/cron-expression rlanvin/php-rrule
    php artisan vendor:publish --provider="DirectoryTree\Cadence\CadenceServiceProvider"
    php artisan migrate
    
  3. Model Integration:

    • Add HasSchedules trait to target models:
      class Report extends Model implements Schedulable {
          use HasSchedules;
      }
      
    • Seed initial schedules via:
      • Database seeds.
      • Admin UI (if built).
      • Migration data.
  4. Event System:

    • Register listeners for ScheduleTriggered:
      // app/Listeners/GenerateReport.php
      public function handle(ScheduleTriggered $event) {
          if ($event->schedulable instanceof Report) {
              ReportJob::dispatch($event->schedulable);
          }
      }
      
    • Use shouldQueue() to filter by model type.
  5. Scheduler Setup:

    • Add to routes/console.php:
      Schedule::command('schedules:run')
          ->withoutOverlapping()
          ->everyMinute();
      
    • Deploy with Laravel’s scheduler (e.g., Supervisor, Kubernetes CronJob).
  6. Testing:

    • Unit tests: Mock ScheduleTriggered events.
    • Integration tests: Verify schedules:run command processes due schedules.
    • Edge cases: Test timezones, recurrence rules, and concurrent runs.
  7. Deprecation:

    • Replace ad-hoc cron jobs with Cadence where possible.
    • Phase out legacy scheduling logic (e.g., Artisan::call() in routes).

Compatibility

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.
ilhamsyabani/laravel-volt-starter
thethunderturner/filament-latex
ghostcompiler/laravel-querybuilder
webrek/laravel-telescope-mongodb
anousss007/blatui
zatona-eg/zatona-eg-api
cocosmos/filament-sticky-save-bar
patrickbussmann/oauth2-apple
3brs/enterprise-security-bundle
anousss007/vigilance
supportpal/eloquent-model
ardenexal/fhir-models
laravel-at/laravel-image-sanitize
romalytar/yammi-audit-log-laravel
ardenexal/fhir-validation
arshaviras/weather-widget
laravel-chronicle/core
sunchayn/nimbus
daikazu/eloquent-salesforce-objects
unseen-codes/chat