What the F*ck Is With All the Artisan Commands: Schedules
Scheduled tasks will be a core part of our application’s life cycle. We need to be able to send invoices every month and reminder users of upcoming items. Laravel provides a clean interface for quickly setting up scheduled tasks.
Without Laravel’s Scheduler
Unix based operating systems have a system know as cron that provides us with the ability to schedule specific commands at specific times. This system works extremely well but has some downsides when we’re using it to schedule lots of tasks in our application.
As we’ve discussed in our article about why we should be building our cron tasks inside our application. Maintaining anything more than a few items becomes a maintenance nightmare inside the normal cron system.
For example, we might have the following list of tasks inside the /etc/crontab
file (the file where system-wide tasks are stored).
As the number of items gets larger and larger it gets harder to maintain this file and some items may get removed accidentally as we make changes. Thankfully, Laravel provides a much easier way to maintain our scheduled tasks.
Running the Schedule
Laravel provides an artisan
command that allows us to run the schedule we’ve defined in our application.
Generally, in other articles from this series, we list out the --help
output for the artisan
commands we’re talking about but this one is so basic there isn’t any need. To start, we’re just going to run the command.
Because this is a new project without any scheduled tasks it displays “No scheduled commands are ready to run.”.
The tasks that should be run are stored in app/Console/Kernel.php
in the schedule()
function. Initially, it will look like this:
The commented out section of the function will run the inspire
command every hour. As a quick side when it says hourly()
it means at the beginning of the hour.
For demonstrative purposes, let’s uncomment that command and set it to run every minute.
Now when we run schedule:run
it will run the command.
That’s great but how do we get this to work with our application? The best way to interact with the schedule is to have it run jobs (which we talked about in “What the F*ck Is With All the Artisan Commands: Queues”). Using Laravel’s jobs class, allows us to create small self-contained classes that do what we need and prevent bloat in the kernel.php
file.
To do this we’ll pass an instance of our job as a parameter to the Schedule
’s job()
function.
Timezone Worries
When running tasks Laravel uses the timezone in our php.ini which may not match up with your internal view of when it should run. To help alleviate this, Laravel’s schedule component allows us to specify the timezone the command should run at.
For example, if we had a job we wanted to run every Friday at 7 AM in the Eastern Time Zone we would run it like so.
As a general rule, we recommend against this unless it’s necessary. When the “daylight saving” portion of the year starts and ends, there is a duplication of or skipping of that hour.
As an example, in the eastern timezone daylight savings time starts at 2 AM and we immediately skip that hour and it becomes 3 AM. Then when daylight savings time ends we repeat 2 AM to 3 AM twice. If we schedule a job to run at 2:30 AM it might run twice or not at all those days.
When Can We Run Jobs?
The frequency of the job is controlled by the function we call at the end of the chain. The code below causes jobs to run every hour.
The Laravel documentation provides a complete list of options but due to Laravel’s conventions we can generally guess the names of the functions.
We can also have the job run based intervals of time which are helpful for when we need to run something very routinely.
You can also limit it to run during business hours.
And on a specific day of the week or weekdays/weekends.
If those don’t provide enough flexibility, Laravel provides a cron()
function that will allow us to specify a crontab expression.
Running the Schedule Automatically
We’ve been running the schedule manually so far but we’re going to want this to operate automatically. To do this we’re going to edit /etc/crontab/
and enter the following line (this assumes our application root is /var/www
and we have write access to /etc/crontab
).
In Closing
Laravel’s scheduler allows us a great deal of flexibility to schedule jobs when we need them to run. Using jobs allows us to easily maintain them and if they’re running using a background worker they can be fault-tolerant.
Scott Keck-Warren
Scott is the Director of Technology at WeCare Connect where he strives to provide solutions for his customers needs. He's the father of two and can be found most weekends working on projects around the house with his loving partner.
Top Posts
- Working With Soft Deletes in Laravel (By Example)
- Fixing CMake was unable to find a build program corresponding to "Unix Makefiles"
- Upgrading to Laravel 8.x
- Get The Count of the Number of Users in an AD Group
- Multiple Vagrant VMs in One Vagrantfile
- Fixing the "this is larger than GitHub's recommended maximum file size of 50.00 MB" error
- Changing the Directory Vagrant Stores the VMs In
- Accepting Android SDK Licenses From The OSX Command Line
- Fixing the 'Target class [config] does not exist' Error
- Using Rectangle to Manage MacOS Windows