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

effiana/cron

A Laravel package for managing and running cron-style scheduled tasks within your application. Define jobs, configure timing, and trigger execution from the CLI or scheduler, providing a simple way to centralize recurring task automation in Laravel.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require effiana/cron
    

    Add the service provider to config/app.php:

    Effiana\Cron\CronServiceProvider::class,
    
  2. Publish Config

    php artisan vendor:publish --provider="Effiana\Cron\CronServiceProvider" --tag="config"
    

    This generates config/cron.php with default settings.

  3. Define a Job Create a job class (e.g., app/Jobs/ProcessReport.php):

    namespace App\Jobs;
    
    use Effiana\Cron\Contracts\JobInterface;
    
    class ProcessReport implements JobInterface
    {
        public function run()
        {
            // Your logic here
        }
    }
    
  4. Register the Job Add the job to config/cron.php under jobs:

    'jobs' => [
        'process-report' => [
            'class' => \App\Jobs\ProcessReport::class,
            'schedule' => '0 0 * * *', // Runs daily at midnight
        ],
    ],
    
  5. Run the Scheduler Add a command to your app/Console/Kernel.php:

    protected function schedule(Schedule $schedule)
    {
        $schedule->command('cron:run')->everyMinute();
    }
    

    Then run:

    php artisan schedule:run
    

First Use Case: Logging a Scheduled Task

Extend JobInterface to log execution:

use Effiana\Cron\Contracts\JobInterface;
use Illuminate\Support\Facades\Log;

class LogTest implements JobInterface
{
    public function run()
    {
        Log::info('Cron job executed at: ' . now());
    }
}

Register it in config/cron.php:

'jobs' => [
    'log-test' => [
        'class' => \App\Jobs\LogTest::class,
        'schedule' => '* * * * *', // Runs every minute
    ],
],

Implementation Patterns

1. Job Registration

  • Dynamic Registration: Use a facade to register jobs programmatically:
    use Effiana\Cron\Facades\Cron;
    
    Cron::addJob('dynamic-job', \App\Jobs\DynamicJob::class, '*/5 * * * *');
    
  • Environment-Based Scheduling: Load jobs from .env:
    CRON_JOBS=backup-database=0 3 * * *,clean-logs=0 4 * * *
    
    Parse in a service provider:
    $jobs = explode(',', env('CRON_JOBS'));
    foreach ($jobs as $job) {
        [$name, $schedule] = explode('=', $job);
        Cron::addJob($name, \App\Jobs\BackupDatabase::class, $schedule);
    }
    

2. Job Dependencies

  • Chaining Jobs: Use after() to chain jobs:
    Cron::addJob('job-a', \App\Jobs\JobA::class, '*/10 * * * *')
        ->after('job-b');
    
  • Conditional Execution: Implement shouldRun() in your job:
    class ConditionalJob implements JobInterface
    {
        public function shouldRun(): bool
        {
            return config('app.maintenance_mode') === false;
        }
    
        public function run() { ... }
    }
    

3. Error Handling

  • Global Exception Handler: Override app/Exceptions/Handler.php:
    public function register()
    {
        $this->renderable(function (Throwable $e, $request) {
            if ($e instanceof \Effiana\Cron\Exceptions\JobException) {
                Log::error('Cron job failed: ' . $e->getMessage());
            }
        });
    }
    
  • Retry Mechanism: Use Laravel’s built-in retry decorator:
    use Illuminate\Support\Facades\Bus;
    
    Bus::dispatchNow((new \App\Jobs\RetryableJob())->retryUntil(3));
    

4. Integration with Laravel Queues

  • Queue Jobs: Extend JobInterface to use queues:
    use Illuminate\Bus\Queueable;
    
    class QueuedJob implements JobInterface
    {
        use Queueable;
    
        public function run() { ... }
    }
    
  • Dispatch via Cron:
    Cron::addJob('queue-job', \App\Jobs\QueuedJob::class, '*/5 * * * *');
    

5. Logging and Monitoring

  • Custom Logger: Bind a logger in the service provider:
    $this->app->singleton(\Psr\Log\LoggerInterface::class, function () {
        return new \Monolog\Logger('cron', [
            new \Monolog\Handler\StreamHandler(storage_path('logs/cron.log')),
        ]);
    });
    
  • Track Execution Time: Log start/end times in run():
    $start = microtime(true);
    // Job logic
    Log::info('Job took ' . (microtime(true) - $start) . ' seconds');
    

Gotchas and Tips

1. Configuration Quirks

  • Timezone Mismatch: Ensure config/app.php timezone matches your server’s timezone. Cron schedules are evaluated in the server’s timezone by default.
  • Missing Config: If jobs don’t run, verify config/cron.php is published and properly structured. Default config may not include all keys.

2. Debugging

  • Check Last Run: Add a last_run_at column to a jobs table and log it in run():
    public function run()
    {
        \DB::table('jobs')->where('name', 'log-test')->update([
            'last_run_at' => now(),
        ]);
    }
    
  • Enable Debug Mode: Set 'debug' => true in config/cron.php to log schedule evaluations.

3. Performance Pitfalls

  • Long-Running Jobs: Avoid blocking jobs. Offload to queues or use dispatchSync() sparingly.
  • Database Locks: If jobs interact with the same tables, use transactions or optimistic locking:
    DB::transaction(function () {
        // Job logic
    });
    

4. Extension Points

  • Custom Schedules: Extend the Effiana\Cron\Schedule class to support custom syntax (e.g., "every 90 minutes").
  • Job Events: Listen for job events using Laravel’s event system:
    \Effiana\Cron\Events\JobStarting::class,
    \Effiana\Cron\Events\JobCompleted::class,
    
  • Dynamic Schedules: Fetch schedules from an API or database:
    $schedule = \App\Models\CronSchedule::where('job_name', 'dynamic-job')->first()->cron_expression;
    Cron::addJob('dynamic-job', \App\Jobs\DynamicJob::class, $schedule);
    

5. Common Issues

  • Jobs Not Running:
    • Verify php artisan schedule:run is in your server’s cron (e.g., * * * * * cd /path-to-project && php artisan schedule:run >> /dev/null 2>&1).
    • Check Laravel’s queue worker is running (php artisan queue:work).
  • Schedule Syntax Errors: Use crontab.guru to validate expressions.
  • Missing Dependencies: Ensure illuminate/support and illuminate/console are installed (this package relies on Laravel’s core).

6. Testing

  • Mock the Cron: Use Laravel’s Schedule facade in tests:
    public function test_cron_job()
    {
        $this->app->make(\Effiana\Cron\CronManager::class)->addJob('test-job', \App\Jobs\TestJob::class, '* * * * *');
        $this->app->make(\Illuminate\Console\Scheduling\Schedule::class)->call('test-job');
        // Assertions
    }
    
  • Time Travel: Use Laravel’s travel() to test schedules:
    use Illuminate\Foundation\Testing\TimeTravelsTo;
    
    class CronTest extends TestCase
    {
        use TimeTravelsTo;
    
        public function test_scheduled_job()
        {
            $this->travelTo(now()->addMinutes(1));
            $this->app->make(\Effiana\Cron\CronManager::class)->runPending();
            // Assert job ran
        }
    }
    
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.
besmartand-pro/php-quality-config
sentix/ai-chatbot
codifyo/ts-generator-bundle
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
spatie/mailcoach-vapor