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

aequasi/cron-bundle

Symfony bundle for registering and running recurring tasks via annotated Console Commands. Scan commands with cron:scan, then execute due jobs with cron:run. Uses DateInterval specs (e.g., PT1H) and works with a system cron to trigger runs periodically.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation Run composer require aequasi/cron-bundle "~1.0.0" to add the bundle to your project. Register the bundle in AppKernel.php:

    new Aequasi\Bundle\CronBundle\AequasiCronBundle(),
    
  2. First Use Case: Define a Cron Job Create a Symfony command (e.g., app/console make:command MyCronJob). Annotate it with @Cron to define its schedule:

    use Aequasi\Bundle\CronBundle\Annotation\Cron;
    
    class MyCronJob extends ContainerAwareCommand
    {
        /**
         * @Cron("*/5 * * * *")
         */
        protected function configure()
        {
            $this->setName('my:cronjob');
        }
    
        protected function execute(InputInterface $input, OutputInterface $output)
        {
            // Your logic here
        }
    }
    
  3. Scan and Run Scan for annotated commands:

    app/console cron:scan
    

    Execute all scheduled jobs:

    app/console cron:run
    
  4. System Cron Setup Add a system cron job to trigger cron:run at your desired interval (e.g., */5 * * * * for every 5 minutes).


Implementation Patterns

Workflows

  1. Command-Based Scheduling

    • Use Symfony commands for modularity and reusability.
    • Annotate commands with @Cron to define schedules (e.g., */10 * * * * for hourly).
    • Example:
      /**
       * @Cron("0 * * * *") // Run at the start of every hour
       */
      protected function configure() { ... }
      
  2. Dependency Injection

    • Inject services into commands via ContainerAwareCommand or constructor injection.
    • Example:
      class MyCronJob extends ContainerAwareCommand
      {
          protected function execute(InputInterface $input, OutputInterface $output)
          {
              $this->getContainer()->get('my.service')->doWork();
          }
      }
      
  3. Logging and Output

    • Use Symfony’s OutputInterface to log job execution:
      $output->writeln('Job executed at ' . new \DateTime());
      
    • Redirect output to a file for debugging:
      app/console cron:run > /var/log/cron.log 2>&1
      
  4. Dynamic Scheduling

    • Override schedules dynamically (e.g., via config or environment variables):
      $schedule = $this->getContainer()->getParameter('cron.schedule.myjob');
      /**
       * @Cron($schedule)
       */
      
  5. Webhook Integration

    • Expose cron:run as a web endpoint (e.g., via Symfony’s HttpKernel) for cloud cron services (e.g., AWS CloudWatch Events, Cron-job.org).

Integration Tips

  1. Database Cleanup

    • Schedule periodic cleanup jobs:
      /**
       * @Cron("0 3 * * *") // Run daily at 3 AM
       */
      protected function configure() { ... }
      
  2. External API Polling

    • Poll APIs at fixed intervals:
      /**
       * @Cron("*/15 * * * *") // Every 15 minutes
       */
      protected function execute(InputInterface $input, OutputInterface $output) {
          $client = $this->getContainer()->get('http_client');
          $client->request('GET', 'https://api.example.com/data');
      }
      
  3. Event-Driven Triggers

    • Combine with Symfony events to react to application state changes.
  4. Environment-Specific Scheduling

    • Use different schedules per environment (dev/staging/prod) via config:
      # config.yml
      parameters:
          cron.schedules:
              myjob_dev: "* * * * *"
              myjob_prod: "0 * * * *"
      

Gotchas and Tips

Pitfalls

  1. Schedule Parsing Errors

    • Invalid cron expressions (e.g., */9 * * * *) will silently fail. Validate schedules using libraries like cron-expression.
    • Fix: Use a helper method to validate:
      private function isValidCron(string $expression): bool {
          return CronExpression::isValidExpression($expression);
      }
      
  2. Overlapping Executions

    • Jobs may run concurrently if cron:run is triggered before the previous execution finishes.
    • Fix: Use locks (e.g., Symfony’s LockFactory) or ensure idempotency.
  3. Time Zone Issues

    • Cron expressions use the server’s local time zone. Ensure consistency across environments.
    • Fix: Set a consistent time zone in config.yml:
      framework:
          timezone: UTC
      
  4. Missing cron:scan

    • Forgetting to run cron:scan means annotated commands won’t be registered.
    • Fix: Add a post-install script to composer.json:
      "scripts": {
          "post-install-cmd": [
              "php app/console cron:scan"
          ]
      }
      
  5. Symfony 3+ Compatibility

    • The bundle is untested on Symfony 3+. Use at your own risk or fork the package.
    • Fix: Check for deprecations (e.g., ContainerAwareCommandCommand with DI).

Debugging

  1. Dry Runs

    • Test schedules without executing logic by mocking the command:
      app/console cron:scan --env=test
      app/console cron:run --env=test --dry-run
      
  2. Logging

    • Enable debug mode to log cron execution:
      app/console cron:run --env=dev
      
    • Check logs for errors or missed executions.
  3. Manual Triggering

    • Run individual commands manually to debug:
      app/console my:cronjob
      

Tips

  1. Idempotent Design

    • Ensure commands are idempotent (safe to rerun) to handle missed executions.
  2. Rate Limiting

    • Use sleep() in commands to avoid hitting API rate limits:
      sleep(60); // Wait 1 minute between retries
      
  3. Environment Variables

    • Store sensitive data (e.g., API keys) in environment variables and inject them:
      $apiKey = getenv('MY_API_KEY');
      
  4. Custom Annotations

    • Extend the @Cron annotation to add metadata (e.g., priority, timeout):
      /**
       * @Cron(expression="*/5 * * * *", priority=10)
       */
      
  5. Monitoring

    • Track job execution via a database table or external service (e.g., Sentry, Datadog).
  6. Fallback for Missed Runs

    • Implement a "catch-up" mechanism for jobs that missed their window:
      $lastRun = $this->getLastRunTime();
      if ($lastRun < $expectedRunTime) {
          // Execute logic for missed window
      }
      
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