Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
API page: https://api.drupal.org/api/drupal/core!core.api.php/function/hook_cron/8...
This code in the sample code won't do anything:
$expires = \Drupal::state()->get('mymodule.cron_last_run', REQUEST_TIME);
as 'mymodule.cron_last_run' won't have been set as a value in state.
This is what works:
$last_cron_run = \Drupal::state()->get('system.cron_last');
Might be worth also mentioning how to get the last cron run time in the docs?
Comment | File | Size | Author |
---|---|---|---|
#11 | update-cron-example-2778461-11.patch | 1.75 KB | apaderno |
#6 | update-cron-example-2778461-6.patch | 1.75 KB | apaderno |
Comments
Comment #2
apadernoActually,
\Drupal::state()->get('mymodule.cron_last_run', REQUEST_TIME)
does what it needs to do: It gets the value set with\Drupal::state()->set('mymodule.cron_last_run', $value)
, if such call was made, orREQUEST_TIME
.There is also a difference between
\Drupal::state()->get('mymodule.cron_last_run', REQUEST_TIME)
and\Drupal::state()->get('system.cron_last')
: The first gets the last time thehook_cron()
implementation of that module has been executed, while the second gets the last time cron tasks were executed. Since it could be that not all thehook_cron()
implementations are invoked, for example because one of the implementations raised an exception, the two values are not necessary the same.Probably,
'mymodule.cron_last_run'
is not the best ID to use. I would rather use'mymodule.last_check'
, which is similar to'update.last_check'
used fromupdate_cron()
. At least, it would not give to users the wrong impression they need to use their own state value to know the last time cron tasks were ran.Comment #3
joachim CreditAttribution: joachim commentedAh right, that makes sense. Though:
> Since it could be that not all the hook_cron() implementations are invoked, for example because one of the implementations raised an exception, the two values are not necessary the same.
The cron runner catches exceptions from each hook_cron() implementation, though it's true that one implementation could cause a timeout and so prevent execution of others, so as you say, implementation should use their own state value to know for certain when they last ran.
Though the default of REQUEST_TIME seems wrong to me. If I am finding out when my implementation last run, it's to do something with things that have happened since the last run (eg, all entities created since last cron run). If the state value isn't set, then I want all entities since the beginning of time, so it should be 0.
Comment #4
apadernoYes... And that is why the Aggregator module uses
\Drupal::state()->get('update.last_check') ?: 0
.Also, let's not use deprecated functions. The part copied from
aggregator_cron()
is also old code, since it now uses (Feed::loadMultiple()
and\Drupal::entityQuery()
copy that code again.Comment #5
joachim CreditAttribution: joachim commentedWouldn't that be cleaner like this:
Updating issue title to expand it to generally cleaning up the sample code here.
Comment #6
apadernoThis is my patch based on the suggestions.
Comment #7
joachim CreditAttribution: joachim commentedLooks good to me.
Comment #9
apadernoIt is strange: It says the patch failed the test, but I see all the tests passing.
Comment #11
apadernoComment #12
joachim CreditAttribution: joachim commentedComment #13
alexpottCommitted and pushed 493eac1 to 8.3.x and 76dbd64 to 8.2.x and 1aee773 to 8.1.x. Thanks!