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

Cron Bundle Laravel Package

byfareska/cron-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the Package

    composer require byfareska/cron-bundle
    

    Add to config/bundles.php if not auto-discovered:

    return [
        // ...
        Byfareska\CronBundle\ByfareskaCronBundle::class => ['all' => true],
    ];
    
  2. Configure the Cron Job Add this line to your system's crontab (e.g., /etc/crontab or via crontab -e):

    * * * * * php /path/to/your/project/bin/console cron:run
    

    Replace /path/to/your/project with your Laravel project root.

  3. Create Your First Task Implement ScheduledTask in a service class:

    namespace App\Tasks;
    
    use Byfareska\Cron\Task\ScheduledTask;
    use DateTimeInterface;
    use Symfony\Component\Console\Output\OutputInterface;
    
    final class CleanupOldLogsTask implements ScheduledTask
    {
        public function cronInvoke(DateTimeInterface $now, bool $forceRun, OutputInterface $output): bool
        {
            // Run daily at midnight
            if ($forceRun || $now->format('H:i') === '00:00') {
                $this();
                $output->writeln('Cleanup logs executed at ' . $now->format('Y-m-d H:i:s'));
                return true;
            }
            return false;
        }
    
        public function __invoke(): void
        {
            // Your cleanup logic here
        }
    }
    
  4. Tag the Task for Auto-Discovery Register the task as a service with the cron.task tag in config/services.php:

    return [
        // ...
        'tags' => [
            'cron.task' => [
                App\Tasks\CleanupOldLogsTask::class,
                // Add other tasks here
            ],
        ],
    ];
    
  5. Test Manually Run the cron command manually to verify:

    php artisan cron:run
    

Implementation Patterns

Task Design Patterns

  1. Conditional Execution Use cronInvoke() to control when tasks run based on:

    • Time (e.g., format('i') === '0' for hourly tasks).
    • External flags (e.g., $forceRun for manual triggers).
    • Business logic (e.g., check database state before running).

    Example: Run a backup task every 3 hours:

    public function cronInvoke(DateTimeInterface $now, bool $forceRun, OutputInterface $output): bool
    {
        if ($forceRun || $now->format('G') % 3 === 0) {
            $this();
            return true;
        }
        return false;
    }
    
  2. Dependency Injection Inject services (e.g., repositories, HTTP clients) into your task:

    final class SendDailyReportTask implements ScheduledTask
    {
        public function __construct(
            private readonly ReportService $reportService,
            private readonly Mailer $mailer
        ) {}
    
        public function cronInvoke(DateTimeInterface $now, bool $forceRun, OutputInterface $output): bool
        {
            if ($forceRun || $now->format('H') === '09') { // 9 AM daily
                $this();
                return true;
            }
            return false;
        }
    
        public function __invoke(): void
        {
            $report = $this->reportService->generate();
            $this->mailer->send($report);
        }
    }
    
  3. Output Handling Use OutputInterface to log task execution:

    $output->writeln('Task started at ' . $now->format('Y-m-d H:i:s'));
    $output->section('Processing data...');
    $output->writeln('Task completed successfully.');
    
  4. Error Handling Wrap task logic in try-catch and log errors:

    public function __invoke(): void
    {
        try {
            // Risky operations
        } catch (\Throwable $e) {
            $output->writeln('<error>Task failed: ' . $e->getMessage() . '</error>');
            // Optionally rethrow or log to a monitoring service
        }
    }
    

Workflows

  1. Development Workflow

    • Manual Testing: Use php artisan cron:run --task=YourTask to test tasks without waiting for cron.
    • Debugging: Pass --verbose or --debug flags to the cron command for detailed output.
    • Dry Runs: Add a DRY_RUN environment variable to skip actual operations:
      if (env('DRY_RUN')) {
          $output->writeln('<comment>Skipping execution (dry run mode)</comment>');
          return true;
      }
      
  2. Deployment Workflow

    • Cron Configuration: Ensure the cron job is added to the server’s crontab during deployment (e.g., via Ansible, Terraform, or a deployment script).
    • Task Registration: Use a TaskRegistry service to dynamically register tasks (advanced):
      $container->register(
          new Definition(CleanupOldLogsTask::class),
          ['tags' => ['cron.task']]
      );
      
  3. Task Scheduling

    • Complex Schedules: Combine multiple conditions for advanced scheduling:
      public function cronInvoke(DateTimeInterface $now, bool $forceRun, OutputInterface $output): bool
      {
          $isWeekday = $now->format('N') <= 5; // Monday=1, Sunday=7
          $isBusinessHour = $now->format('H') >= 9 && $now->format('H') <= 17;
      
          if ($forceRun || ($isWeekday && $isBusinessHour && $now->format('i') === '0')) {
              $this();
              return true;
          }
          return false;
      }
      
  4. Integration with Laravel

    • Service Providers: Register tasks in a Laravel service provider:
      public function register()
      {
          $this->app->tag([
              App\Tasks\CleanupOldLogsTask::class,
          ], 'cron.task');
      }
      
    • Artisan Commands: Extend the bundle’s commands or create custom ones:
      php artisan cron:run --task=YourTask --force
      

Gotchas and Tips

Pitfalls

  1. Cron Job Timing

    • Issue: Cron jobs may not run exactly on the minute due to system load or delays.
    • Fix: Use a small time window (e.g., format('i') <= 2 for "every 2 minutes") or implement a "missed run" check:
      public function cronInvoke(DateTimeInterface $now, bool $forceRun, OutputInterface $output): bool
      {
          $lastRun = $this->storage->getLastRunTime();
          if ($forceRun || ($now->getTimestamp() - $lastRun->getTimestamp()) >= 3600) { // 1 hour
              $this();
              $this->storage->setLastRunTime($now);
              return true;
          }
          return false;
      }
      
  2. Task Registration

    • Issue: Tasks not auto-discovered if not tagged correctly.
    • Fix: Verify tags with:
      php artisan debug:container --tag=cron.task
      
    • Manual Registration: For dynamic tasks, use:
      $this->app->tag([YourDynamicTask::class], 'cron.task');
      
  3. Output Buffering

    • Issue: Console output may not appear if the cron job runs in the background.
    • Fix: Redirect output to a file or use a logging service:
      * * * * * php /path/to/your/project/bin/console cron:run >> /var/log/cron.log 2>&1
      
  4. Time Zone Handling

    • Issue: DateTimeInterface uses the system time zone by default.
    • Fix: Set the time zone explicitly:
      $now = new DateTime('now', new DateTimeZone('America/New_York'));
      
  5. Long-Running Tasks

    • Issue: Tasks may time out if they run longer than the cron job’s timeout (e.g., 5 minutes).
    • Fix:
      • Break tasks into smaller chunks.
      • Use a queue system (e.g., Laravel Queues) for background processing.
      • Increase the timeout in the cron job command (if possible).

Debugging Tips

  1. Log Everything Use OutputInterface or a logger (e.g., Monolog) to track task execution:
    $output->writeln('Task started');
    try {
        $this();
        $output->writeln('Task succeeded');
    } catch (\Throwable $e) {
        $output->w
    
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.
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope