Upgrade Your Drupal Skills
We trained 1,000+ Drupal Developers over the last decade.
See Advanced Courses NAH, I know EnoughGuide to Ultimate Cron
Drupal comes with its own built in cron. This means that you can add your own job to the list of jobs that are executed when the Drupal cron runs.
Drupal runs all of these jobs at the same time. What happens if you want to run one particular cron job really frequently? You have to change your cron settings to run ALL of them that frequently. It’s an all or nothing affair and you end up running all the cron jobs as often as your most frequent job. That can put a lot of pressure on your web server.
A second problem is if you have a job that requires a lot of heavy lifting. With these jobs, you might want to run them overnight when traffic to your site is lighter and there is less pressure on the web server. But with Drupal’s built in cron, you can’t do that either because of the all or nothing nature of it. You run it once or not at all.
To solve this problem, you need a way to separate cron jobs so that you can run each job, or groups of jobs, at different times. There are two main options to achieve that - Elysia Cron and Ultimate Cron. In this article, we are going to look at Ultimate Cron because that is available for Drupal 7 and 8, where as Elysia Cron is Drupal 7 only.
Download and install the module
In Drupal 8, the recommended way to add a new module to your project is to use composer. The following composer command will download Ultimate Cron and add it to the list of dependencies.
composer require drupal/ultimate_cron
You can then enable the module manually by going to the Extend admin menu item, or by using Drush.
Create a new job
You can create a new job by implementing hook_cron()
in a custom module. The following example implements hook_cron()
in a module called custom_utility. When this job is run, it will log a message to Drupal’s logs.
function custom_utility_cron() {
\Drupal::logger('custom_utility')->notice('Cron ran');
}
You can change the code in the function to execute what you need. The call to log a message is purely to demonstrate that this cron job is actually running.
Discover the job
Head over to configuration -> cron in the admin menu (/admin/config/system/cron/jobs). You should see a list of jobs from various core modules.
Hit the Discover jobs button and the job you created above will appear on the list.
To test that this works, click Run. Then head over to recent log messages (admin/reports/dblog) and you should see the message.
To edit the frequency of the job, click on the arrow to the right of the Run button and click edit. In the scheduler tab you can change the frequency in the Run cron every X minutes drop down to.
Export the configuration
At this point, you can export the configuration using Drupal’s standard configuration export. You can then import the configuration if you use a staging and production site. If you are unsure how to export and import configuration, check out the configuration management documentation on Drupal.org.
Adding more than one job for a module
If your custom module only needs to support one cron job, then you have enough to do that. You can add additional code to your implementation of hook_cron()
(see custom_utility_cron()
above) and that will run when your cron job runs at the scheduled time.
But what if you want to have more than one cron job running at different times all from this one custom module?
You can do this by defining each multiple cron job with their own call back function. The call back function is used instead of hook_cron()
.
The settings for each Ultimate Cron job is stored in its own configuration file. Drupal uses YAML for configuration files, and you’ll need to create these files. The following steps will outline how to do this.
Steps to add a cron job
- In the admin menu, go to Configuration -> Configuration synchronisation (/admin/config/development/configuration)
- Click on the Export tab and then the Single item sub-tab (/admin/config/development/configuration/single/export)
- Change Configuration type to Cron job
- Change Configuration name to Default cron handler with the name of your custom module. In my case, this is Default cron handler (
custom_utility_cron
). - Copy the configuration code to your clipboard
In your custom module:
- Create a
config
directory in the root of your custom module’s directory - Create a new file:
ultimate_cron.job.jobname.yml
(changejobname
to the name of your job) - Paste the configuration code you copied earlier
Here is an example of what this code will look like:
uuid: fa40bf2b-f544-4e22-b4b9-dda9cc0efbfe
langcode: en
status: true
dependencies:
module:
- custom_utility
title: 'Default cron handler'
id: custom_utility_cron
weight: 0
module: custom_utility
callback: custom_utility_cron
scheduler:
id: simple
configuration:
rules:
- '*/15+@ * * * *'
launcher:
id: serial
configuration:
timeouts:
lock_timeout: 3600
launcher:
thread: 0
logger:
id: database
configuration:
method: '3'
expire: 1209600
retain: 1000
There are a couple of adjustments to make to this file:
- Remove the uuid line (the first line)
- Change the id to something unique e.g. id: custom_utility_cron_job1
- Change the title to something meaningful so that you can distinguish this job in the cron admin page
This file is creating a new job for Drupal to run. Let’s break it down:
- callback: custom_utilty_cron - this is the call back function that will be run when this job runs.
- module: - this is your custom module. This is also the module where you should add your call back function
- scheduler: - this is the schedule to which this job will run, which for this one is every 15 minutes
The next thing to do is to add the callback to the .module file in your module.
Here is an example:
/**
* The callback for the cron job.
*/
function custom_utility_callback() {
\Drupal::logger('custom_utility')->notice('Cron ran');
}
This call back function will be run every time this job is executed.
And then go back to the configuration file from above and change the callback function to point to this function. In my example, this means changing this line:
callback: custom_utility_cron
To:
callback: custom_utility_callback
Repeat
You can then repeat these steps for any additional cron jobs that you need, with a new configuration YAML file and call back function for each.
Import the new config
In order for this to work, you need to import the configuration that you set up above. This can be done with the following command (change custom_utility to the name of your module):
drush config-import --source=modules/custom/custom_utility/config --partial -y
Wrapping up
Separating cron jobs out is often necessary to give you the control you need to run jobs at different times. Ultimate Cron is a wonderful module that allows you to do just that.
About Drupal Sun
Drupal Sun is an Evolving Web project. It allows you to:
- Do full-text search on all the articles in Drupal Planet (thanks to Apache Solr)
- Facet based on tags, author, or feed
- Flip through articles quickly (with j/k or arrow keys) to find what you're interested in
- View the entire article text inline, or in the context of the site where it was created
See the blog post at Evolving Web