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 Job Laravel Package

draw/cron-job

Manage cron jobs stored in the database: queue due jobs and execute them via Symfony Messenger workers. Includes console commands to enqueue due jobs or run by name, optional Sonata Admin pages, and Doctrine ORM mapping configuration.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps to First Use

  1. Installation:

    composer require draw/cron-job
    

    Ensure symfony/messenger and doctrine/orm are installed (or use Laravel’s Doctrine bridge if needed).

  2. Configuration: Add to config/packages/draw_framework_extra.yaml (or Laravel’s equivalent):

    draw_framework_extra:
      cron_job:
        enabled: true
        doctrine:
          orm:
            mappings:
              DrawCronJob:
                is_bundle: false
                type: attribute
                dir: "%kernel.project_dir%/vendor/draw/cron-job/src/Entity"
                prefix: "Draw\Component\CronJob\Entity"
    
  3. Messenger Setup: Configure config/packages/messenger.yaml (or Laravel’s config/messenger.php):

    framework:
      messenger:
        transports:
          async: "%env(MESSENGER_TRANSPORT_DSN)%" # e.g., 'doctrine://default'
        routing:
          Draw\Component\CronJob\Message\ExecuteCronJobMessage: async
    
  4. Database Migrations: Run Doctrine migrations to create cron_job and cron_job_execution tables:

    php bin/console doctrine:migrations:diff
    php bin/console doctrine:migrations:migrate
    
  5. First Cron Job: Create a cron job via the admin panel (Sonata) or manually:

    use Draw\Component\CronJob\Entity\CronJob;
    $cronJob = new CronJob();
    $cronJob->setName('send-nightly-reports');
    $cronJob->setSchedule('0 0 * * *'); // Daily at midnight
    $cronJob->setCommand('app:send-reports'); // Your Laravel command
    $entityManager->persist($cronJob);
    $entityManager->flush();
    
  6. Trigger Due Jobs: Run the command to process overdue jobs (schedule this via cron):

    php bin/console draw:cron-job:queue-due
    
  7. Manual Execution: Test a job manually:

    php bin/console draw:cron-job:queue-by-name send-nightly-reports
    

Implementation Patterns

Core Workflows

1. Defining and Managing Cron Jobs

  • Database-First: Store cron jobs as entities (CronJob) with fields like name, schedule (cron expression), command, enabled, and last_run_at.
  • Admin Integration: Use SonataAdmin (or custom UI) to CRUD jobs without touching code.
  • Example Entity:
    // src/Entity/CronJob.php (extend Draw\Component\CronJob\Entity\CronJob)
    class AppCronJob extends CronJob {
        // Custom fields or logic
    }
    

2. Queue-Based Execution

  • Symfony Messenger: Jobs are enqueued as ExecuteCronJobMessage and processed asynchronously.
  • Laravel Queue Alternative: Override the CronJobProcessor to dispatch to Laravel’s queue:
    // app/Services/CustomCronJobProcessor.php
    use Illuminate\Support\Facades\Bus;
    
    class CustomCronJobProcessor implements CronJobProcessorInterface {
        public function process(CronJob $cronJob) {
            Bus::dispatch(new HandleCronJob($cronJob));
        }
    }
    
  • Transport Configuration: Use Laravel’s supported transports (Redis, database) in Messenger:
    transports:
      async: 'doctrine://default' # or 'redis://localhost'
    

3. Command Integration

  • Laravel Commands: Reference existing Laravel commands (e.g., app:send-reports) in CronJob::setCommand().
  • Custom Logic: Extend ExecuteCronJobMessageHandler to add pre/post-execution logic:
    // app/MessageHandlers/CustomCronJobHandler.php
    use Draw\Component\CronJob\Message\ExecuteCronJobMessage;
    
    class CustomCronJobHandler implements MessageHandlerInterface {
        public function __invoke(ExecuteCronJobMessage $message) {
            // Pre-execution logic
            $exitCode = shell_exec($message->getCommand());
            // Post-execution logic
            return $exitCode;
        }
    }
    

4. Execution Tracking

  • Automatic Logging: The package creates CronJobExecution records for every run, including:
    • started_at, ended_at, duration
    • exit_code, output, error_output
  • Query Executions:
    $executions = $entityManager->getRepository(CronJobExecution::class)
        ->findBy(['cronJob' => $cronJob]);
    

5. Scheduled Processing

  • Cron Trigger: Schedule the queue-due command in your server’s cron:
    * * * * * php /path/to/your/project/bin/console draw:cron-job:queue-due
    
  • Laravel Task Scheduler: Alternatively, use Laravel’s scheduler (if not using Symfony Messenger):
    // app/Console/Kernel.php
    protected function schedule(Schedule $schedule) {
        $schedule->command('draw:cron-job:queue-due')->everyMinute();
    }
    

Integration Tips

Laravel-Specific Adaptations

  1. Doctrine + Eloquent:

    • Use a repository pattern to bridge Doctrine entities and Eloquent:
      // app/Repositories/CronJobRepository.php
      class CronJobRepository {
          public function findByName(string $name) {
              return CronJob::query()->where('name', $name)->first();
          }
      }
      
  2. Service Container:

    • Bind Symfony services to Laravel’s container in config/services.php:
      'Draw\Component\CronJob\CronJobProcessor' => \Draw\Component\CronJob\CronJobProcessor::class,
      
  3. Artisan Commands:

    • Register the package’s commands in app/Console/Kernel.php:
      protected $commands = [
          \Draw\Component\CronJob\Command\QueueDueCronJobsCommand::class,
          \Draw\Component\CronJob\Command\QueueCronJobByNameCommand::class,
      ];
      

Advanced Patterns

  1. Job Dependencies:

    • Implement a depends_on field in CronJob to chain jobs (e.g., job_b runs after job_a).
    • Example logic in CronJobProcessor:
      $dependentJobs = $entityManager->getRepository(CronJob::class)
          ->findBy(['depends_on' => $cronJob->getName()]);
      
  2. Dynamic Scheduling:

    • Override CronJob::isDue() to add dynamic conditions (e.g., run only on weekdays):
      public function isDue(): bool {
          return parent::isDue() && now()->dayOfWeek !== \Carbon\Carbon::SUNDAY;
      }
      
  3. Event Dispatching:

    • Listen for CronJobExecuted events to trigger notifications or analytics:
      // app/Listeners/CronJobExecutedListener.php
      use Draw\Component\CronJob\Event\CronJobExecuted;
      
      class CronJobExecutedListener {
          public function handle(CronJobExecuted $event) {
              Log::info("Cron job {$event->getCronJob()->getName()} executed");
          }
      }
      
  4. Rate Limiting:

    • Add a max_runs_per_hour field to CronJob and validate in CronJobProcessor:
      $lastRuns = $entityManager->getRepository(CronJobExecution::class)
          ->count(['cronJob' => $cronJob, 'createdAt' => now()->subHour()]);
      if ($lastRuns >= $cronJob->getMaxRunsPerHour()) {
          throw new \RuntimeException('Rate limit exceeded');
      }
      

Gotchas and Tips

Pitfalls

  1. Symfony-Laravel Conflicts:

    • Issue: Symfony Messenger and Laravel’s queue system may conflict if both are configured to use the same transport (e.g., Redis).
    • Fix: Use separate queue connections or configure Messenger to use Doctrine’s transport:
      transports:
        async: 'doctrine://default' # Avoids Redis conflicts
      
  2. Doctrine vs. Eloquent:

    • Issue: The package uses Doctrine ORM, which may clash with Laravel’s Eloquent migrations.
    • Fix: Use a shared repository or manually merge migrations. Example:
      php bin/console doctrine:migrations:execute --query="CREATE TABLE IF NOT EXISTS cron_job (...)"
      
  3. **C

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.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky