There seem to be a number of problems with modules or nodes with PHP code doing funny things when their code is invoked during hook_cron(). Many of these problems could be avoided by making code conditional on not being called by cron. But there is the problem of detecting whether or not this code is being invoked by cron.
Hacks:
- An uncommitted but suggested hack in #453296: drupal_goto breaks cron.php uses $_SERVER['REQUEST_URI'] or $_SERVER['SCRIPT_NAME'].
- #397592: Site index is always 0% and running cron.php redirects to user/1/edit fixes buggy code in the correct way, but using $user->uid as a generalized check won't work in other situations.
I suggest that there should be a new drupal API function defined to detect whether or not a cronjob is running.
Return value: TRUE if hook_cron() is being run, FALSE otherwise. This function should not return TRUE just because the cron_semaphore is grabbed or just because hook_cron() _was_ called -- I think this latter note is important because otherwise poormanscron might be broken(?)
Name: Please come up with a better name, my best idea is cron_running_hooks(). This name hopefully makes it obvious that the function will not return TRUE just because cron_semaphore is locked.
My concerns: I do not know how the ``queues'' stuff works. It would seem that cron_running_hooks() should return TRUE when queues are being run. Thoughts?
Sorry for the patch against DRUPAL-6, have made modifications to HEAD but couldn't test them yet because I don't have PDO installed yet.
| Comment | File | Size | Author |
|---|---|---|---|
| #54 | drupal-cron_is_running-888998_0.patch | 4.99 KB | franz |
| #52 | drupal-cron_is_running-888998_0.patch | 5 KB | franz |
| #46 | drupal-cron_is_running-888998.patch | 5 KB | franz |
| #43 | drupal-cron_is_running-888998.patch | 4.99 KB | franz |
| #38 | drupal-cron_is_running-888998-38.patch | 5.1 KB | disasm |
Comments
Comment #1
franzSomehow related: #1217668: drupal_path_initialize() should not call drupal_get_normal_path() when run from cron.php.
Comment #2
franzCould be only cron_running, to avoid being confused with another hook...
Comment #3
franzTriggering test to make issue alive
Comment #5
franzI renamed the function to fit the pattern and re-rolled the patch
Comment #6
franzWould be nice to have some tests here to ensure cron runs code that has drupal_goto().
Comment #7
franz#5: 888998-drupal-cron-is-running.patch queued for re-testing.
Comment #9
franzRe-rolling
Comment #10
xjmSome mechanism like this seems like a really good idea. I'm hesitant about adding it to the globals, though. Maybe someone smarter than me can weigh in on that.
Here's a couple of minor cleanups.
Minor thing, but I'd change this to "Checks whether cron hooks are being called and queues are being run."
And let's capitalized "Queues" here, I think.
Also, note that the Drupal 8.x patch will need to be rerolled, because the core directory structure for Drupal 8 has now changed. (For more information, see #22336: Move all core Drupal files under a /core folder to improve usability and upgrades). When the patch has been rerolled, please set the issue back to "Needs Review."
Tagging as novice for the task of rerolling the Drupal 8.x patch, including fixing the two points I describe above.
If you need help rerolling this patch, you can come to core office hours or ask in #drupal-gitsupport on IRC.
Comment #11
xjmExcept there was a validation error and I failed to set the status or the tag. Oops.
Comment #12
kathyh commentedPatch for #10 (sans any mod to the concept of adding it to the globals).
Comment #13
kathyh commentedfixed spaces introduced in #12
Comment #14
franzYes, I was thinking, and leaving the global also did not make sense if using a function, so I made it a static variable, not sure if that was the best way of implementing it.
Comment #15
tstoecklerWhy not kill the function entirely and do:
Then instead of
people can do
??
I think that would be a little less overhead code-wise.
Comment #16
xjm#15 seems like a better solution to me as well, especially since memory overhead is a concern on cron. I'll roll a patch and test with that method.
Comment #17
franzMmm, I don't like the idea. This value is supposed to be used to determine if the CURRENT request is a cron run.
variable_set() will cause all parallel requests to believe they're being run on a cron.
Comment #18
franzAlso, memory overhead is minimal (couple of lines of code and a static variable?) and O(1), so it's not that much of a concern.
Comment #19
xjm#17: Oh, that is an excellent point. Doh. So #14 is the correct solution, then.
I'll rewrite my test for #14 instead.
Comment #20
xjmAttached test-only patch tests whether
drupal_cron_is_running()returns the expected value at various points. (Note: The patch includesdrupal_cron_is_running()to avoid undefined function fatals, but does not use it during cron.) Should fail.Comment #21
xjmWhoops. I'll fix this in the combined patch. This won't affect the demonstration that the test fails, though. :P
Comment #22
franzJust noticed this is not conforming to doc standards... Should be a newline sentence with a period.
23 days to next Drupal core point release.
Comment #23
xjm#22 Did you look at the most recent patch? I already changed that.
Still waiting on testbot here before I upload the combined.
Comment #25
xjm'Bout time. Fails on the correct assertion. Now, the combined patch. This is the one to review.
Comment #26
franzNo, sorry. Test failed fine, we're almost done here. =)
Comment #27
franzOps, cross-post...
Comment #28
xjmOh, I just realized that I didn't add test coverage for this case.
Oh, wait. Actually, I think that this functionality hasn't been added yet. I think we'd need to add setting and unsetting the flag around the bit below? Can anyone weigh in on whether this is correct (and something we want to do) before I reroll anything again?
Comment #29
franzDo you mean setting the same flag when processing any queue?
Comment #30
xjm#29: Hmm sorry, I don't understand the question. Maybe too early in the morning. :)
This is what I mean. Change the snippet in #28 to:
The comments for
drupal_cron_is_running()appear to claim that we're doing this, but we're not yet.Comment #31
franzYes, that's it, I guess this makes it complete.
Comment #32
xjmAlright, will try to add that and come up with some test coverage for it.
Comment #33
xjmSo, three tasks:
common_test.moduleis now insidecore/modules/system/testsandCronRunTestCasewill have been renamed and moved for PSR-0; look incore/modules/system/lib/Drupal/system/tests//Comment #34
hawkeye.twolfI've re-rolled the patch and added drupal_cron_is_running() around the queue code (tasks 1 and 2 from #33).
Task "3. Add additional test coverage for when the flag should be TRUE." from #33 still needs to be addressed.
Comment #36
hawkeye.twolfWhoops - patch fixed now, plus an interdiff.
Comment #37
hawkeye.twolfHere's a few more details about my patch. It patch contains two things: (1) the reroll to reflect the changed file structure and line numbers of the PSR-0 testing scheme, and (2) the added code to use the new drupal_cron_is_running() function around the processing of queued cron tasks.
The interdiff shows the changes between the reroll and the added code (no interdiff for the reroll).
Comment #38
disasm commentedreroll!
Comment #40
disasm commented#38: drupal-cron_is_running-888998-38.patch queued for re-testing.
Comment #41
disasm commentedreceived these same exact failures in 1209674. Appears to be a testbot fluke. Resending.
Comment #42
tstoecklerSome minor improvement suggestions, but all in all I think this warrants a "needs work".
I couldn't really come up with a better suggestion, but $value seems random.
This makes it sound like you should explicitly pass NULL instead of just omitting the variable alltogether. I think we could just omit the second clause in the first sentence.
I think this should mention that this only applies to cron queues, i.e. queues that have set the cron key.
This should be simply $drupal_cron_is_running = FALSE;
That said, the variable is too verbose. The drupal part is superfluous at the very least.
Comment #43
franzAddressed #42
Comment #45
tstoecklerI was gonna mark this RTBC, but the bot is smarter than me...
This should be $running as well.
Comment #46
franzComment #47
franzSame here. I think we already have tests.
Comment #48
ParisLiakos commentedAny reason why we introduce a variable here? it should be config
Comment #49
franzThe reason is that the patch is older than those changes.
Comment #50
franzI'm still confused by the new API. Should this be converted to a state or a config?
Comment #51
ParisLiakos commentedah..yes you are right, it should be state
Comment #52
franzLet's see now.
Comment #54
franzForgot the variable_get(). Done right this time, hopefully.
Comment #55
tstoecklerLooks great!
Comment #56
catchI'm not sure about this. Most of the examples involve doing things like drupal_goto(), which is almost always a bad idea (since it completely halts script execution). This could go wrong for anything invoked by drush, not necessarily just cron.
Comment #57
catchAlso I'd expect this to tell me whether cron is running on the site at all with the current name - drush ev "print drupal_cron_is_running()" for example.
Comment #58
franzre #57... it is meant exactly for that, if it doesn't work, needs to be fixed.
Comment #59
franzI see what you mean, I forgot the original idea about it. We need to set a state there.
Comment #60
franzAfter reviewing the discussion, I read myself saying that no, the purpose is exactly to tell whether cron is running on current call, so that stuff running inside cron jobs will know it and do things differently.
Comment #62
socketwench commentedNovice issue cleanup.
Comment #63
gung wang commented54: drupal-cron_is_running-888998_0.patch queued for re-testing.
Comment #78
smustgrave commentedThank you for sharing your idea for improving Drupal.
We are working to decide if this proposal meets the Criteria for evaluating proposed changes. There hasn't been any discussion here for over 8 years which suggests that this has either been implemented or there is no community support. Your thoughts on this will allow a decision to be made.
Since we need more information to move forward with this issue, the status is now Postponed (maintainer needs more info). If we don't receive additional information to help with the issue, it may be closed after three months.
Thanks!
Comment #79
smustgrave commentedWill give this one more bump, if no interest will close in 3 months, thanks all!
Comment #80
smustgrave commentedThis had a lot of comments so giving 1 final bump.
With
Is this still needed?
Comment #81
mjpa commentedI'm not sure it's needed as mentioned in previous comments some of the scenarios aren't advised anyway.
If its something seen as a good thing to have, I'd favour adding a method to the cron service rather than checking the lock. Another module could change the cron service and use a different way of setting that cron is running.