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

Scheduler Bundle Laravel Package

aurimasniekis/scheduler-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require aurimasniekis/scheduler-bundle
    

    Add to config/bundles.php:

    AurimasNiekis\SchedulerBundle\AurimasNiekisSchedulerBundle::class => ['all' => true],
    
  2. Cron Configuration: Add to your server’s crontab (runs every minute):

    * * * * * /path/to/laravel/bin/console scheduler:run >> /dev/null 2>&1
    
  3. First Job: Create a job class in app/Jobs:

    namespace App\Jobs;
    
    use AurimasNiekis\SchedulerBundle\ScheduledJobInterface;
    
    class SendDailyReport implements ScheduledJobInterface
    {
        public function __invoke(): void
        {
            // Your logic here (e.g., send email, process data)
            \Log::info('Daily report sent!');
        }
    
        public function getSchedulerExpression(): string
        {
            return '0 9 * * *'; // Runs daily at 9 AM
        }
    }
    
  4. Verify Jobs: Check registered jobs with:

    php artisan scheduler:list
    

Implementation Patterns

Core Workflow

  1. Job Registration:

    • Implement ScheduledJobInterface (auto-registered via Symfony’s autoconfigure).
    • Use NamedScheduledJobInterface for custom job names (e.g., for CLI execution).
  2. Cron Expressions:

    • Use standard cron syntax (e.g., * * * * * for every minute, 0 0 * * 0 for weekly Sundays).
    • Validate expressions with dragonmantank/cron-expression (included).
  3. Manual Execution:

    • Trigger jobs ad-hoc:
      php artisan scheduler:execute SendDailyReport
      
      or for named jobs:
      php artisan scheduler:execute named_job
      
  4. Dependency Injection:

    • Inject services into jobs via constructor (Laravel-style):
      class SendReport implements ScheduledJobInterface {
          public function __construct(private Mailer $mailer) {}
      
          public function __invoke(): void {
              $this->mailer->send(...);
          }
          // ...
      }
      
  5. Logging and Monitoring:

    • Log job execution in __invoke() (e.g., Log::info()).
    • Use scheduler:list to debug next run times or missed executions.

Integration Tips

  1. Laravel-Specific Adjustments:

    • Replace Symfony’s config/bundles.php with Laravel’s config/app.php (if using Laravel):
      'providers' => [
          AurimasNiekis\SchedulerBundle\AurimasNiekisSchedulerBundle::class,
      ],
      
    • Use Laravel’s Artisan facade for commands:
      use Illuminate\Support\Facades\Artisan;
      Artisan::call('scheduler:run');
      
  2. Environment-Specific Scheduling:

    • Override cron expressions per environment (e.g., .env):
      class SendReport implements ScheduledJobInterface {
          public function getSchedulerExpression(): string {
              return env('SCHEDULER_EXPRESSION', '0 9 * * *');
          }
      }
      
  3. Job Chaining:

    • Chain jobs by triggering them from another job’s __invoke():
      public function __invoke(): void {
          Artisan::call('scheduler:execute BackupDatabase');
      }
      
  4. Testing:

    • Mock the scheduler in PHPUnit:
      $this->app->bind(ScheduledJobInterface::class, function () {
          return $this->createMock(ScheduledJobInterface::class);
      });
      

Gotchas and Tips

Pitfalls

  1. Cron Tab Misconfiguration:

    • Ensure the cron job path is correct (use absolute paths).
    • Test cron syntax with crontab -l and */1 * * * * echo "test".
  2. Time Zone Issues:

    • Cron runs in the server’s time zone. Use DateTime::setTimezone() in jobs if needed:
      $now = new DateTime('now', new DateTimeZone('America/New_York'));
      
  3. Job Overlaps:

    • Avoid overlapping executions by adding locks (e.g., Laravel’s Lock):
      use Illuminate\Contracts\Bus\QueueingDispatcher;
      use Illuminate\Bus\PendingDispatch;
      
      public function __invoke(): void {
          if (app(QueueingDispatcher::class)->lockFor('send_report', now()->addMinutes(10))) {
              // Execute logic
          }
      }
      
  4. Dependency Injection Quirks:

    • Laravel’s service container may not autowire Symfony-style interfaces. Explicitly bind services if needed:
      $this->app->bind(ScheduledJobInterface::class, function ($app) {
          return new SendReport($app->make(Mailer::class));
      });
      
  5. Outdated Package:

    • Last release was in 2020. Verify compatibility with Laravel 10+ (may require patches or forks).

Debugging Tips

  1. Check Job Execution:

    • Redirect cron output to a log file:
      * * * * * /path/to/laravel/bin/console scheduler:run >> /var/log/scheduler.log 2>&1
      
    • Use scheduler:list to verify next run times.
  2. Manual Testing:

    • Test jobs manually before deploying cron:
      php artisan scheduler:execute SendDailyReport
      
  3. Logging:

    • Add debug logs in __invoke():
      \Log::debug('Job started', ['class' => static::class]);
      try {
          // Logic
      } catch (\Throwable $e) {
          \Log::error('Job failed', ['error' => $e->getMessage()]);
      }
      
  4. Expression Validation:

    • Validate cron expressions programmatically:
      use Cron\CronExpression;
      $expression = new CronExpression('*/5 * * * *');
      if (!$expression->isValid()) {
          throw new \RuntimeException('Invalid cron expression');
      }
      

Extension Points

  1. Custom Job Storage:

    • Extend the bundle to store jobs in a database (e.g., track runs, failures):
      // Example: Add a `runs` table and log executions in __invoke().
      
  2. Dynamic Expressions:

    • Fetch expressions from config or API:
      public function getSchedulerExpression(): string {
          return config('scheduler.expressions.send_report');
      }
      
  3. Event Dispatching:

    • Dispatch events before/after job execution (e.g., JobStarting, JobCompleted):
      use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
      
      class SendReport implements ScheduledJobInterface {
          public function __construct(private EventDispatcherInterface $dispatcher) {}
      
          public function __invoke(): void {
              $this->dispatcher->dispatch(new JobStarting());
              // Logic
              $this->dispatcher->dispatch(new JobCompleted());
          }
      }
      
  4. Retry Mechanism:

    • Implement retries for failed jobs (e.g., using Laravel’s retry helper):
      use Illuminate\Support\Facades\Retry;
      
      public function __invoke(): void {
          Retry::retry(3, function () {
              // Logic that might fail
          });
      }
      
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.
daikazu/eloquent-salesforce-objects
unseen-codes/chat
romalytar/yammi-jobs-monitoring-laravel
kisame76/filament-db-table-state
nqxcode/laravel-lucene-search
dpfx/laravel-livewire-wizards
workos/workos-php-laravel
sofa/laravel-global-scope
nawasara/auth-primitives
adhocrat-io/arkhe-main
make-dev/orca-harpoon
itsemon245/lamet
baks-dev/dashboard
amoifr/pickle-panther-bundle
make-dev/orca
dmstr/symfony-system-resources-bundle
dmstr/symfony-job-queue-bundle
dmstr/openapi-json-schema-bundle
dmstr/keycloak-security-bundle
dmstr/doctrine-audit-log-bundle