Kriptic's avatar

cron and scheduler how they work together

* * * * * php /path/to/artisan schedule:run >> /dev/null 2>&1

This Cron will call the Laravel command scheduler every minute. When the schedule:run command is executed, Laravel will evaluate your scheduled tasks and runs the tasks that are due.

I'm using forge, so this part is no problem, but here's where I get confused.

let's say I wanted to add this to console/kernel.php

$schedule->command('emails:send --force')->everyMinute();

So, the cron is running every minute, but the schedule is running every minute, won't this just create a &*^%load of instances? Or does Laravel just know that something is running as part of it's evaluation when running the scheduler?

I don't get how the two play together...

0 likes
5 replies
Snapey's avatar

cron fires the scheduler, scheduler checks what tasks need starting that minute. If the task keeps running into the next minute then you would now have two instances. If they keep running then after a further minute there would be three tasks.

The point being, the task should do what it needs to do and stop.

Kriptic's avatar

The way I'm understanding this, is I could do this two ways, but the fact that I can do it these two ways, makes no sense..

for example, I can schedule a cron that runs every minute, which runs the scheduler, which would be:

$schedule->command('emails:send --force')

and that's fine

but it seems I can also run the cron, what, like once daily and do this:

$schedule->command('emails:send --force')->everyMinute();

So laravel will run that task every minute until what, the server crashes?

I only have to run the scheduler once, and laravel will fire the task every minute, so why have the cron in the first place?

I must be missing something...

Snapey's avatar
Snapey
Best Answer
Level 122

Definitely something is missing !! ;-)

Look. You use the cron job on your server to trigger artisan scheduler to run - ideally every minute.

ok, clear so far? The scheduler runs once per minute.

Then in the app/Console/Kernel.php schedule method you list commands that you want the scheduler to check. So each time the scheduler is fired (once per minute) it goes through the schedule() method and starts any command or function that matches the truth test for the desired interval

eg

    protected function schedule(Schedule $schedule)
    {
        $schedule->command('inspire')->hourly();

        $schedule->command('auth:clear-resets')->daily();

    }

So this fires the inspire command every hour and clears password resets at midnight every day.

In both cases, the command runs until its finished and the scheduler then checks the next command.

If any command takes more than a minute then there is a problem. Suppose 'inspire took two minutes to run. When the scheduler got to the second command it would no longer be midnight (but say 00:02) and not pass the test and be skipped over.

Back to your question, if you say everyMinute() then the command always be truthy and will always run - but only when the scheduler has been fired.

If you said ->everyTenMinutes(); then the command is run only when the minutes are 00,10,20,30 etc

Kriptic's avatar

OOOHHHHHHHHHH!

Now I get it. lol

So, the point is that Laravel acts like a wrapper on top of cron, so you don't have to mess with adding crons, it's all in the code.

and I guess ideally every minute (the scheduler) because, well it depends on what all your tasks are, etc

ok I'm good now

Really appreciate you taking the time to break that down for me.

Snapey's avatar

It doesn't stop you still firing cron jobs for other reasons, but this way your tasks are included in your project not something you have to remember to do to the server after deployment.

Glad it clicked!

Please or to participate in this conversation.