Problem/Motivation
Core added Drupal\Core\Queue\DelayableQueueInterface in Drupal 9.1.0, with #3116478: Add a way to silently keep an item locked when processing a queue via cron. Its single method, delayItem($item, int $delay), sets the expiry of the current claim on an item to the current time plus $delay seconds. The item stays claimed until then, and becomes available again after that.
Core's DatabaseQueue implements it, and Drupal\Core\Cron uses it: when a queue worker throws DelayedRequeueException, cron calls delayItem() with the delay from the exception if the queue implements the interface. Otherwise, cron leaves the item's current claim alone, so the item becomes available again when its original claim expires. No item is lost; only the delay requested by the worker is ignored.
The mongodb_storage queue was written in #3130220: Implement the queue service before the interface existed, and does not implement it.
Most contrib queue backends do not implement it either. This comparison covers the default development branch of each project, as found in its code on 2026-09-30:
| Project, branch, class | Declares Drupal 10/11 | DelayableQueueInterface |
releaseItem() on an item that is not claimed |
|---|---|---|---|
core DatabaseQueue, Batch |
yes | yes | TRUE |
core Memory, BatchMemory |
yes | no | FALSE |
mongodb 8.x-2.x Queue |
yes | no | FALSE |
mongodb 3.x: core DatabaseQueue on the MongoDB database driver, with a core patch adapting its queries |
Drupal 11.1 only | yes, core's | TRUE: the driver's updates return the matched count |
redis 2.x RedisQueue, ReliableRedisQueue |
yes | no | TRUE |
| redis 8.x-1.x, all queue classes | yes | no | no return value (NULL) |
rabbitmq 4.x Queue |
Drupal 10 only | no | throws an Error |
kafka 8.x-1.x KafkaQueue |
yes | no | TRUE |
queue_unique 8.x-2.x UniqueDatabaseQueue |
no (Drupal 8/9) | yes, inherited from DatabaseQueue |
TRUE, inherited |
aws_sqs 8.x-1.x AwsSqsQueue |
no (Drupal 8/9) | no | depends on the AWS response |
aws_sqs_api 1.0.x AwsSqsQueue |
no (Drupal 9) | no | no return value (NULL) |
beanstalkd 8.x-1.x BeanstalkdQueue |
no (Drupal 8) | no | no return value (NULL) |
openstack_queues 8.x-1.x OpenstackQueue |
no (Drupal 8) | no | FALSE |
advancedqueue 8.x-1.x, own backend API instead of QueueInterface |
yes | not applicable: every backend must accept a delay in enqueueJob() and retryJob() |
not applicable: releasing is the optional SupportsReleasingJobsInterface::releaseJob() |
Advanced Queue is the exception in design rather than in interface: it does not implement QueueInterface, but its own backend API makes delays mandatory, and its processor retries failed jobs after a delay, which is what delayItem() provides for core queues.
So among the compared backends not built on core's DatabaseQueue, none implements the interface. The last column shows that behavior also varies where the core interface leaves room, which this plan should keep in mind when deciding how closely to follow core.
Proposed resolution
Evaluate whether the MongoDB queue should implement DelayableQueueInterface, then either:
- create a feature request to implement it, or
- document in
docs/modules/mongodb_storage.mdthat the queue does not implement it, why, and what happens instead when a worker throwsDelayedRequeueException.
Points to evaluate:
- Use: which core and contrib queue workers throw
DelayedRequeueException, and how often sites would run such workers on a MongoDB queue. - Cost: the queue already stores the claim expiry in
expires, andclaimItem()already treats items with an expired claim as available, sodelayItem()would be a single update ofexpires, likereleaseItem(). Tests could follow core'sCronQueueTest::testDelayedRequeue(). - Compatibility: whether a MongoDB queue meant as a replacement for core's
DatabaseQueueshould support what it supports, given that other backends do not. - Interaction with #3626957: Implement or document ReliableQueue support or lack thereof: whether delaying items affects the ordering guarantees evaluated there.
Remaining tasks
- Evaluate the points above.
- Decide, and record the decision in this issue.
- Either create the feature request, or update the documentation.
User interface changes
None.
API changes
None in this plan. A resulting feature request would make Queue also implement DelayableQueueInterface, an addition that does not break callers.
Data model changes
None.
AI disclosure
Issue created with AI asssitance.
Comments
Comment #2
fgm