laravelcronscheduler

How can i use scheduler in seconds manner in Laravel 5.#


there i am trying to schedule some task in larave, but i find it hard to schedule my task in every 20 seconds. Checking laravel doc. for laravel schedular, it didn't have such method for seconds. While there is ->cron('* * * * * *') "Run the task on a custom Cron schedule", but it also couldn't solve my problem.

Below is my code in kernal.php file for scheduling.

protected function schedule(Schedule $schedule)
{ 
    // need to replace everyMinute() by some other method which can run it every 20 sec

    $schedule->call('path\to\controller@method)->everyMinute();

   // also tried cron() but didn't workout.
    $schedule->call('path\to\controller@method)->cron(*/20 * * * * *);
}    

Thanks.


Solution

  • There's no method that will do this for you out of the box, however there are a few suggestions of people who have been in the same situation as you already.

    ->cron(*/20 * * * * *) is actually saying run this every 20 minutes, not every 20 seconds. Given that cron doesn't go down to a sub-minute resolution this is probably why Laravel doesn't support it either.

    If this really needs to run more than every 30 seconds then I would go for a combination of the two here: Laravel 5 schedule job every 30 seconds and Laravel schedular: execute a command every second

    That is to say, you should still call your command every minute, but add the withoutOverlapping() method just to be safe.

    Then inside your command you can run your code, sleep for 20 seconds, run it again, sleep for 20 seconds, and then run it again. This obviously works on the premise that your code is almost instantaneous to run. For example, if your code takes 5 seconds to run and then you sleep for 20 seconds and then run it again - your code is actually running every 25 seconds.

    I imagine you have a fairly good idea of how long this code takes to run. If not, time it manually whilst running the artisan command to get an idea - something like this might help date && php artisan your:command && date. This will output the date in your shell, run the command then output the date again - this includes the time which you can use to see how many seconds it takes to run.

    This will require you to either refactor the controller action out to a command or add the sleep() code to your controller action. The docs for artisan commands should help here.

    I would suggest refactoring this into a command, but it's up to you.

    //Console command
    public function handle()
    {
        \App\Investment::calculate(); //takes 2 seconds to run
        sleep(18); //sleep for 18 seconds to ensure we are only running the command every 20 seconds
        \App\Investment::calculate(); //takes 2 seconds to run
        sleep(18);
        \App\Investment::calculate(); //takes 2 seconds to run
    }
    
    
    //The console scheduler - Kernel.php  
    protected function schedule(Schedule $schedule)
    {     
        $schedule->call('path\to\controller@method)->everyMinute()->withoutOverlapping();
    }