Drupal Cron
Blog

Schedule Automated Tasks in Drupal with Cron

Cron, A daemon/background process that runs at periodic intervals of time. It can be run periodically at pre-decided times and intervals. To describe in real-time, I have met with a case where I have to fetch the content from a site, where new content might be created everyday and create it on my site. To handle this, I have created a cron job, configured it to run every day at a specific time let’s say at 05.00 AM. So whenever the cron runs, I have written a script to fetch the content that is created on that day and creating on my site. All this is achieved using the cron in Drupal.

Cron is a utility which executes commands at set intervals known as "cron jobs".
According to drupal.org “A "cron job" is a time-triggered action that is usually (and most efficiently) performed by your website's hosting server, but can also be configured by a remote service or even from your own desktop”.

Related: How to Handle Intensive Tasks on Queue With Drupal Queue API

Where can we use?

It can be used for Importing files, sending emails, Publishing the code, Fetching the content from an external site every day, etc.

How can this be implemented in D8?

Drupal 8 provides an automated Cron. This is a built-in tool that is time-based task scheduler. The name itself indicates Automated which means no Manual involvement is required other than the initial setup. By default, this cron is set to run every 3 hours. We can change it accordingly for every hour, daily basis, weekly basis as per the requirement. We can even alter the settings form and add our own periodic intervals.

How can we use this Drupal cron to run the custom periodic task?

hook_cron: This hook is triggered whenever the Drupal cron runs. So, we can define our task inside this. For example, I want to check if there are any unpublished nodes, I want to publish them each time when the cron runs.

Now how does execution happen?

  • Execute cron manually from the Drupal admin interface.

  • Using Drush command:

Drush cron

Limitations:

  1. In case we have multiple modules implementing hook_cron, these run at the same time either alphabetically or as per the module weight. This adds more weight to a page request at one point in time.

  2. If one cron results in an error, this stops the cron running which will not process the remaining ones until it is solved. Also, its tough to find out who is the culprit.

  3. If we want to optimize the cron run time, we should analyze which cron run took more time.

To overcome all these limitations, Drupal provides us with modules like Super cron, Elysia cron, Ultimate cron etc.. All these modules are one or the same with more added features. How does this help?

  1. No one by one execution, Its parallel now. So, even if there is an error with one cron task, the other executes independently of each other.

  2. Each can have a separate configuration. so I can say run my cron job at every 1 hour, cron job B at every 2 hrs.

  3. Each has separate logs.

  4. Supports Drupal Queue

Out of all these modules we have, Ultimate cron is available now in D8. This has more features comparatively.

Ultimate Cron:

Ultimate Cron

Misconception: Assume, I have a case where my main cron is set to run for every 3 hours, and my custom cron job task is set to run every one minute. In this case, my cron job doesn’t actually run every one minute. Yes, it’s true. How this actually works is: When any user hits our site, it takes the current timestamp and the last cron run timestamp. If the difference is greater than the cron interval time, our cron job is only triggered then.

How can we make use of ultimate cron for our custom job?

  1. Define a yml for the ultimate cron job in the install folder.

2. Define Callback.

3. Install the module.

4. Go to Cron in UI, click on Discover jobs. This shows the newly created cron job.

Cron with Batch:

We know there are cases where we want to do operations on a large amount of data. For this, we prefer Batch process so that it happens in bulk instead of one by one. For example queue. When we try to update let’s say, 50k of data with almost 20 fields each, it may result in a time out. So we want this to happen in the background process and I want to add content in chunks lets say, 5k of content each time in order to reduce the load. We can use cron with batch.

  1. Define .yml

2. Define Callback

3.Define QueueWorker

Related: Batch Process in Drupal 8

Ultimate cron also facilitates with an option "Override cron Queue processing". This option creates a cron job, automatically for a queue worker.

Limitations:

  • The site should be active. Yes! if the cron is set for 1 hr, it is not compulsory that it keeps running for every 1 hr. it’s a misconception. the cron only runs if there is any user visiting. Which means the site should be active. let’s say if the cron is set for every 3 hrs, and no user visited your site for a week, then the cron doesn’t get triggered.

  • Cron Processing still adds to page request. Whenever the crown runs, it adds load to the page request.

External crons:

These are the ones that can be set up on external sites. We have Easy Cron, Cron Less etc.  So, whether or not there is a user visit, the cron still executes.

To improve the site performance, we can disable the automated cron in ur site. This stops all the cron jobs even that are unnecessarily/unknowingly running on our site. Even we disable the cron, our cron job can still be executed if we are making use of external crons.

To disable the automated cron:

Set the "Run cron every" value to "Never"

                     (OR)

Add the following line to your settings.php:(so that no user can enable it).

$config['automated_cron.settings']['interval'] = 0;