Search code examples
laravellaravel-scheduler

How does it work ? Laravel Schedule Customized with Spatie/laravel-cronless-schedule


I'm using laravel schedule with Spatie/laravel-cronless-schedule package. PHP 7.4 & Laravel 5.6.

I have a confusion that how does it work with time & overlapping.

I have done so far.

    // Noman Command for Send SMS
    $schedule->command('api:elite-send-sms')->everyMinute()->withoutOverlapping();
    $schedule->command('api:metro-send-sms')->everyMinute()->withoutOverlapping();


    // Noman Command for Update Delivery Report
    $schedule->command('EliteUpdateDeliveryStatus:updateStatus')->everyMinute()->withoutOverlapping();
    $schedule->command('MetroUpdateDeliveryStatus:updateStatus')->everyMinute()->withoutOverlapping();

I have run this command by spatie/laravel-cronless-schedule

php artisan schedule:run-cronless --frequency=5

It's helped me to hit the schedule:run command continuously by 5 seconds frequency.

Now I would like to know that when I run the schedule:run-cronless command then what will be happened in my schedule command which is

$schedule->command('api:metro-send-sms')->everyMinute()->withoutOverlapping();

I have run schedule:run-cronless in 5 seconds interval but here its it in everyMinute() and withoutOverlapping()

Now my question is, Is it alright ? or is wrong with me? Or I have done something Illogically?

Any explanation will be highly appreciated.


Solution

  • TL;DR: It might work the way you expect it. But I from your description I would say you should use Laravels Queues.

    If you declare a everyMinute(), in fact this will make laravel run this event on every call of php artisan schedule:run. If you declare it everyFiveMinutes(), it will execute the command on every minute that is divisible by 5 with every call of schedule:run. The Laravel Scheduler is built to be run exactly once per minute.

    The spatie-package, as it clearly says, is made for testing environments.

    Laravel's native scheduler relies on cron to be executed every minute. It's rock solid and in most cases you should stick to using it. I advise you not to use it for production. Also the frequency-argument is obviously ment if you do some testing, to reduce the time you have to wait for an action. Again, you should not depend on it for an production enviroment.

    By using withoutOverlapping() you will eliminate some of the side-effects from running it more frequently. It will work the job through, and will not start a new one if the previous one is still processing.

    However, I think it's pretty obvious that you are using the wrong tool in Laravel to process potentially slow tasks. Lets take your first command api:elite-send-sms for an example. I'm pretty sure you do not want to send the sms every 5 seconds. You would like to send it on an event, and that's what Laravel Queues are for. On the event, you will dispatch a job to the queue, and immidiatelly finish the request, without waiting for the job to be executed.

    You can still use queues, even if your environment can not use redis and Laravel Horizon. But if you can use Horizon, it will make easier for you (after spending a day learning about it).