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.
Problem/Motivation
I have a long running queue worker and the current system doesn't have a way for queue workers to signal "I am not done yet".
Proposed resolution
Allow non-error releaseing an item.
Remaining tasks
User interface changes
API changes
New RequeueException.
Data model changes
Comment | File | Size | Author |
---|---|---|---|
#16 | 2667294_16.patch | 3.05 KB | chx |
#10 | interdiff.txt | 943 bytes | chx |
#10 | 2667294_10.patch | 4.29 KB | chx |
Comments
Comment #2
chx CreditAttribution: chx at Smartsheet commentedComment #3
larowlanCan we get a test for this, we probably already have something that throws the other exception
But love it
Comment #4
chx CreditAttribution: chx at Smartsheet commentedSure thing.
Comment #5
larowlanCan you also assert that the queue size remains at 1?
Ta
Comment #6
larowlanAlso, I think we need some docs updates - and possibly a change notice.
Comment #7
chx CreditAttribution: chx at Smartsheet commentedComment #8
larowlanunless bot disagrees I think this is ready
Comment #9
neclimdulI'm not really keen on using exceptions for control flow but the idea works.
Lets at least change the wording around the exception. The comments about "needs more time" imply things about why the exception was thrown when it could be anything. A resource isn't available yet, it wants to hand off to a different worker, the third moon of Jupiter was out of alignment, the task should only be run on Mondays...
Lets just say "the worker requested the task be immediately requeued" or something along those lines.
Similar changes to the change log.
Extra line before namespace.
Comment #10
chx CreditAttribution: chx at Smartsheet commentedUpdated the change notice too.
Comment #11
cosmicdreams CreditAttribution: cosmicdreams as a volunteer commented@neclimdul isn't that the reason why PHP has Exception types, so that you can handle them conditionally if they occur? This patch looks good to me. If this was the pre-Drupal 8 era, I would suggest that a change notice be written for it as it sounds like a nifty idea that developers would want to know more about.
Edit: my bad, you've already got the change noticed handled.
Comment #12
catchWell it does, but they should really be used for errors (which might have different types), whereas this is not an error, it's just "Not right now thanks".
I opened #2670866: Add return values to QueueWorkerInterface::processItem() instead of using exceptions for code flow to tackle that in 9.x, but I really don't see a way to do it in a bc-compatible way, so exceptions seems like the only choice here.
Comment #14
catchCommitted/pushed to 8.1.x, thanks!
Comment #15
neclimdulRight, thanks catch. What I try to emphasis when using exceptions is that exceptions should be exceptional. Typed exceptions exist so you can handle different exceptional cases. That means there can be different flows based on the exception but they should not be used for flow.
The way I think of it is this, if you are developing a feature you expect the users to use, you should not be using exceptions. If you are recovering from something —an error or failure in state— then exceptions is appropriate.
I'm not convinced passes that litmus and so should not be handled by exceptions. The API around the return type is exactly why I hesitated though, thanks catch for opening the follow up. This seems like the right approach so we can get the feature in and being used but can develop the right solution.
Comment #16
chx CreditAttribution: chx at Smartsheet commentedReopening with a possible new approach based on the followup; no need to make it D9 IMO.
Edit: this keeps backwards compatibility because there can't be a runner which currently returns this object as this object doesn't yet exist. Returning any scalar would not fit this criteria.
Comment #17
neclimdulThanks for taking my concerns to heart!
So thinking this though, the BC seems to cover the item runner, but I wonder about BC with worker threads. The API goes both ways of course. So if a similar implementation existed in Drush and you run your queue there, if it doesn't handle the return it would normally delete the item since an exception wasn't thrown. Then the item is lost rather then being completed correct?
Comment #18
chx CreditAttribution: chx at Smartsheet commentedWe can add
__drupal_queue_api_version
to $data passed to processItem and then the worker can decide whether to suspend the queue or to immediately requeue.Comment #19
catchThis is why I just committed the patch with the 9.x follow-up, couldn't think of a way to handle bc in both directions.
That could be an option though yes. It will be extra code everywhere, but allow us to add the new return types then remove the bc stuff later which is all you can ask for.
Comment #20
chx CreditAttribution: chx at Smartsheet commented> add the new return types
What typeS?
Comment #21
catchTheoretical new return types we might add other than this one in the future that aren't errors. For example we might want to distinguish between 'keep my place at the front of the queue' vs. 'send me to the back of the queue'.
Comment #22
chx CreditAttribution: chx at Smartsheet commentedI doubt that's possible. The "yardstick" is the ability to use Amazon SQS as the queue backend.
Anyways, I get what you are saying.
Comment #23
catchRight we can't guarantee that a backend supports ordering but I think "don't delete" vs. "recreate" might be fine despite that.
Comment #25
catchThis is already in, so we should open a new issue for any follow-up.