Cron is a daemon
What is Cron
Cron is a daemon that executes commands at specified intervals. These commands are called "cron jobs". Cron is available on Unix, Linux, and Mac servers. Windows servers use a Scheduled Task to execute commands. The actual "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 server or even from your own desktop.
What actually happens is that the cron job visits the cron.php file in your website at a URL like http://www.example.com/cron.php?cron_key=0MgWtfB33FYbbQ5UAC3L0LL3RC0PT3RNUBZILLA0Nf1Re.
You can find the exact address of the cron.php file in the Status report at Administration > Reports > Status report (admin/reports/status) in the section Cron maintenance tasks.
Programming Cron Job
Modules that require some commands to be executed periodically can implement hook_cron().
The engine will then call the hook whenever a cron run happens, as defined by the administrator.
Typical tasks managed by hook_cron() are database maintenance, backups, recalculation of settings or parameters, automated mailing, and retrieving remote data.
Short-running or non-resource-intensive tasks can be executed directly in the hook_cron() implementation.
Long-running tasks and tasks that could time out, such as retrieving remote data, sending email, and intensive file tasks, should use the queue API instead of executing the tasks directly. To do this, first define one or more queues via a \Drupal\Core\Annotation\QueueWorker plugin. Then, add items that need to be processed to the defined queues.
class QueueWorker
Declare a worker class for processing a queue item.
Worker plugins are used by some queues for processing the individual items in the queue. In that case, the ID of the worker plugin needs to match the machine name of a queue, so that you can retrieve the queue back end by calling \Drupal\Core\Queue\QueueFactory::get($plugin_id).
\Drupal\Core\Cron::processQueues() processes queues that use workers; they can also be processed outside of the cron process.
Some queues do not use worker plugins: you can create queues, add items to them, claim them, etc. without using a QueueWorker plugin.
However, you will need to take care of processing the items in the queue in that case.
You can look at \Drupal\Core\Cron::processQueues() for an example of how to process a queue that uses workers, and adapt it to your queue.
Plugin Namespace: Plugin\QueueWorker
Code Snippet
function mymodule_cron() {
// Short-running operation example, not using a queue:
// Delete all expired records since the last cron run.
$expires = \Drupal::state()->get('my_module.last_check', 0);
$request_time = \Drupal::time()->getRequestTime();
\Drupal::database()
->delete('my_module_table')
->condition('expires', $expires, '>=')
->execute();
\Drupal::state()->set('my_module.last_check', $request_time);
// Long-running operation example, leveraging a queue:
// Queue news feeds for updates once their refresh interval has elapsed.
$queue = \Drupal::queue('my_module.feeds');
$ids = \Drupal::entityTypeManager()
->getStorage('my_module_feed')
->getFeedIdsToRefresh();
foreach (Feed::loadMultiple($ids) as $feed) {
if ($queue->createItem($feed)) {
// Add timestamp to avoid queueing item more than once.
$feed->setQueuedTime($request_time);
$feed->save();
}
}
$ids = \Drupal::entityQuery('my_module_feed')
->accessCheck(FALSE)
->condition('queued', $request_time - 3600 * 6, '<')
->execute();
if ($ids) {
$feeds = Feed::loadMultiple($ids);
foreach ($feeds as $feed) {
$feed->setQueuedTime(0);
$feed->save();
}
}
}