Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How Laravel knows when the scheduler has been updated?

My question is more of a general wondering. I have two commands created using Laravel, let's call them A and B.

Each one of these commands are scheduled with the ->dailyAt($par) method. But the $par parameter comes from a query.

I mean something like this:

protected function schedule(Schedule $schedule)
{
    $schedulerTime_commandA = App\Model\CommandsTime::where('id', 1)->first()->time;
    $schedulerTime_commandB = App\Model\CommandsTime::where('id', 2)->first()->time;

    $schedule->command('A')
            ->dailyAt($schedulerTime_commandA);

    $schedule->command('B')
            ->dailyAt($schedulerTime_commandB);
}

This is because the superuser wants to schedule the time when those commands will run. My question here is: How Laravel knows this schedule method within the App\Console\Kernel.php file has been changed?

NOTE: I have the following cron entry as Laravel talks about it on the docs.

* * * * * php /path/to/artisan schedule:run >> /dev/null 2>&1
like image 374
Luis Deras Avatar asked Mar 18 '16 20:03

Luis Deras


People also ask

How does Laravel scheduling work?

The scheduler allows you to fluently and expressively define your command schedule within your Laravel application itself. When using the scheduler, only a single cron entry is needed on your server. Your task schedule is defined in the app/Console/Kernel. php file's schedule method.

How do I know if a cron job is running in Laravel?

Run Schedule Command for a test To check if schedule commands have been constructed successfully, run this command. After that, go to the logs folder inside the storage directory, open the Laravel. php cron job file, and check it. Note: You can use this command when you want a Laravel scheduler without a cron job.

Which file is responsible for scheduling any command in Laravel?

The process of scheduling tasks in Laravel is handled by files such as Kernel. php , Schedule. php , Event. php , ScheduleRunCommand.

How do I schedule a cron job in Laravel?

Now to activate the scheduled jobs, run the Cron command. Go to your application from the Applications tab, and then to the Cron Jobs Manager. When done, make sure to save changes. That's it!


1 Answers

The way Laravel's scheduler system works is it uses a cron job that runs once every minute (that's the * * * * * part in the cron entry: match every minute of every hour of every day of every month of every year).

So every minute, php /path/to/artisan schedule:run >> /dev/null 2>&1 is being run by cron.

When that command runs, it should check the schedule as defined by the schedule() method in the Kernel class when it is run.

So technically, Laravel doesn't know that the schedule has changed, per se. Every minute it should run, hit the schedule() method, which will grab the latest values from the database, and then return the schedule as it is set at that particular minute in time.

Each individual run of the cron knows nothing about the ones that came before it, or the ones that will come after it.

At least that's my understand of the scheduler. I've only spent a little time in the core Laravel Kernel code, but I believe that to what is going on from my own experience.

Hope that helps!


Edit 1

Just confirmed my logic in Laravel's code. Every time the cron script runs, the schedule is rebuilt, so the changes to the schedule in the database will be used the next time the cron entry runs. Laravel doesn't really know that it changed - it just checks every time it runs and uses what it finds.

Specifically, here's the chain through code if it's of interest:

  1. Calling php artisan on the command line will run the artisan file in the project root;
  2. In the artisan file the Application is bootstrapped and a Kernel object is initialized;
  3. When the Kernel class is initialized, the constructor for the Kernel class (Laravel\Lumen\Console\Kernel) calls the defineConsoleSchedule() method on itself;
  4. The defineConsoleSchedule() method initializes a blank Schedule object (Illuminate\Console\Scheduling\Schedule);
  5. The blank Schedule object will be passed to the schedule() method on the Kernel class; and finally
  6. In the schedule() method, which is where you defined your command schedule, your two DB queries will be run, and your two schedule entries will be defined with the values that the DB returns at that moment.

The above actions happen every time the console application bootstraps, which means on every call to php artisan, regardless of what command you wish to run.

When running the schedule:run command specifically, here's what happens next:

  1. After the application bootstraps, the ScheduleRunCommand object (Illuminate\Console\Scheduling\ScheduleRuneCommand) is initialized; and
  2. The fire() method is called on the ScheduleRunCommand object, which runs through all the commands defined on the Schedule object when the application bootstrapped; and
  3. Checks each command to see if that command must be run at that time by calling the isDue() method on the Event (Illuminate\Console\Scheduling\Event) that represents the command; and finally
  4. Each command that needs to be run at that minute, by returning true from isDue() will be run.
like image 60
stratedge Avatar answered Nov 13 '22 09:11

stratedge