This looks like a bug although maybe I'm just not understanding something.

If you look at drupal_cron_run() it has lock functionality which prevents more than one cron process from running at once.

However, the code which processes queue items during cron lives outside of that lock, and thus queue items will be processed every single time cron is called.

This could be an issue especially when combined with the "poormanscron" feature in core. For example, when one (unlucky) person triggers the cron process and gets a slow page request, then before it's complete everyone else who happens to visit the site during that time period seems like they will trigger the processing of queue items (even if they don't trigger the full cron processing) and therefore they might all get slow page requests too..

Issue fork drupal-1875020

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

jhodgdon’s picture

Actually, I don't think this is really a problem. Cron queue jobs have to be written so that they are independent and can be done in a queue -- meaning that they sit there and wait for some process to come along, read them from the queue, and do them. There are several methods of processing the queue (cron, a Drush command, contrib modules, etc.). Each method follows the same steps: "grab" a job, process it, and continue until some limit is reached.

So, it shouldn't matter if the queue is already being processed by some other method (or a previous cron run). Each job needs to be independent, and only one processor can grab a given job that is in the queue.

I'd be inclined to mark this as "works as designed".

David_Rothstein’s picture

Status: Active » Needs review
StatusFileSize
new2.14 KB

Well, maybe not a bug then, but still seems like an issue that we assume/advertise in various places that the poormanscron feature will only result in one unlucky user every X minutes getting a slow page load, when in fact it could result in a whole bunch of them.

The attached patch (completely untested) is what I was thinking of. Actually, if you look at it, it seems like it must be some kind of bug that the existing code for looping through each queue and (re-)creating it only happens when a lock is acquired... but all the other queue processing happens regardless. But I'm not sure if that problem has any actual practical effect.

jhodgdon’s picture

I think this patch is a good idea. +1. I haven't tested it either, but moving the queue operations inside the cron lock check seems like a good idea. Presumably the maintainers of the cron system will tell us why it was done the other way previously?

Nephele’s picture

Status: Needs review » Closed (works as designed)

Sorry, but I think this is an unnecessary patch that breaks how the system is intended to work. The cron queue is supposed to work differently from standard cron jobs, and moving queue operations inside the cron lock removes one of the key differences. As stated in the cron queue documentation:

While there can be only one hook_cron() process running at the same time, there can be any number of processes defined here running. Because of this, long running tasks are much better suited for this API. Items queued in hook_cron() might be processed in the same cron run if there are not many items in the queue, otherwise it might take several requests, which can be run in parallel.

Unless this behavior is causing an actual bug (and the bug is not due to a poorly designed queue item), then I don't see why it should be altered. I'm changing to works as designed.

slip’s picture

Version: 8.0.x-dev » 8.7.x-dev
Issue summary: View changes
Status: Closed (works as designed) » Needs review
StatusFileSize
new620 bytes

Sorry but 6 years later this bug just bit me on a site I'm maintaining and it has nothing to do with a poorly designed queue. The issue is Drupal's automated_cron is set to keep calling cron over and over again on every page load. If you have a long running queue (1 minute say) and you have a lot of traffic, you can easily max out your servers with tons of queues running simultaneously causing the site to crash.

As this is a standard setup we should provide more protection. If the developer wants their queues to be scheduled to run on top of each other, they could easily find other solutions that are more reasonably configured.

I'm submitting a 8.7.x patch to move the call into the lock to at least provide some protection.

Version: 8.7.x-dev » 8.8.x-dev

Drupal 8.7.0-alpha1 will be released the week of March 11, 2019, which means new developments and disruptive changes should now be targeted against the 8.8.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.9.x-dev » 9.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

pmagunia made their first commit to this issue’s fork.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

podarok’s picture

Priority: Normal » Major
Status: Needs review » Reviewed & tested by the community

#13 looks good and fixes an issue

longwave’s picture

I agree with #4, queues are designed to be processed in parallel if there is a lot of work to be done.

For sites that need more control over this they should explicitly call cron from an external cron job (instead of relying on the automatic cron that runs after page loads) or use https://www.drupal.org/project/ultimate_cron

catch’s picture

Hmm I also agree with #4 and #16 however I'm not sure it's an argument against making this change.

If you have dedicated jobs to run down queues, putting the cron queue running inside the cron lock won't prevent them running simultaneously, it'll only stop more than one cron run from trying to process the queues at once.

longwave’s picture

After thinking about this some more, this indeed doesn't harm sites that process queues separately, but it does help the case where cron is run regularly and prevents sites with occasionally-busy queues from running out of resources and trying to process more than one queue at a time.

alexpott’s picture

Running tests against 9.5.x and 10.1.x...

I debated the need for a CR but I think the fact that the warning $this->logger->warning('Attempting to re-run cron while it is already running.'); exists means that people should not be depending on the current behaviour - as they'd be getting loads of warnings.

I've credited everyone who contributed to the discussion even if they thought it was works as designed.

alexpott’s picture

Removing credit for @pmagunia - the patch in #5 still applies to 10.x and 9.x so a new MR was unnecessary.

catch’s picture

Status: Reviewed & tested by the community » Needs work

10.1 failure is real.

longwave’s picture

Status: Needs work » Needs review
StatusFileSize
new3.93 KB
new3.32 KB

The cron unit test needed some updating to match the new behaviour.

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

smustgrave’s picture

Status: Needs review » Needs work
Issue tags: +Needs Review Queue Initiative

This issue is being reviewed by the kind folks in Slack, #needs-review-queue-initiative. We are working to keep the size of Needs Review queue [2700+ issues] to around 400 (1 month or less), following Review a patch or merge request as a guide.

Tested on 10.1.x with a standard install
Applied patch and verified cron still runs from the UI and from an external URL

But think the tests need tweaking. I applied the test changes and removed the update to Cron.php and the tests still pass.

longwave’s picture

Status: Needs work » Needs review

The tests should still pass; however they made assumptions before that are now incorrect if we only update \Drupal\Core\Cron, so the test needed some tweaking in order for it to pass again (see the fail in #5).

smustgrave’s picture

Status: Needs review » Reviewed & tested by the community

Ah thank you for that explanation. In that case the changes look good to me.

  • catch committed e910452a on 10.0.x
    Issue #1875020 by longwave, David_Rothstein, slip, alexpott, catch,...
catch’s picture

Version: 10.1.x-dev » 9.5.x-dev
Status: Reviewed & tested by the community » Fixed

Committed/pushed to 10.1.x, cherry-picked to 10.0.x and 9.5.x, thanks!

  • catch committed d06dfb35 on 10.1.x
    Issue #1875020 by longwave, David_Rothstein, slip, alexpott, catch,...

  • catch committed 15e5495d on 9.5.x
    Issue #1875020 by longwave, David_Rothstein, slip, alexpott, catch,...
wim leers’s picture

Tangentially related: #3318964: automated_cron should not run cron when visiting update.php — that's s another way that cron gets executed but shouldn't. 😅

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.