Problem/Motivation

The method responsible for instantiating the queue backend service for each queue worker \Drupal\Core\Queue\QueueFactory::get uses settings.php to determine if there is service set for requested worker name: 'queue_reliable_service_' . $name and 'queue_service_' . $name.

This means that if a module implements QueueWorker plugin it has no way of saying that the worker should use different backend service instead of the default database one.

This means that either the module overrides the whole queue factory service or possibly the settings service. Either way it is not pleasant.

A concrete example of where this would be useful is for queue items that process orders (e.g. in commerce). Heavier processes should make use of the queue so they are processed behind the scenes. However, if an order is loaded, it may be important to process those items immediately so the order is loaded 'up to date'. The obvious way to do this is to use a queue backend that stores the order ID in a separate field that can be used to query/filter other queue backend methods (e.g. claimItem).

To achieve this currently requires an entirely separate queue process (which means it wont be picked up by cron, drush queue-run etc) or to override the queue factory or settings service.

Proposed resolution

So instead of having hardcoded variable in settings.php I propose a new attribute is added to the QueueWorker annotation class backend_service. This would default to the current queue.database service if no value would be provided.

In the aforementioned method the queue worker plugin would be loaded(already in memory if called from Cron) and if it exists(I'm not sure if there can be a queue that does not have worker set up) and the service name would be retrieved from the plugin definition.

If there is no worker the default database backend would be used.

Remaining tasks

Decide if this is something we are happy to do.

User interface changes

None.

API changes

This solution is backwards compatible without any disruptive changes to the API, but developers wishing to make use of it can define their back end and annotate their worker to utilise it.

Data model changes

None.

Issue fork drupal-2821989

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

Anonymous’s picture

ivanjaros created an issue. See original summary.

sarmiliboyz’s picture

Version: 8.0.x-dev » 8.4.x-dev

current active development branch is 8.4.x-dev

dawehner’s picture

Are there specific usecases you have in mind which are not possible right now? I think it would be conceptually wrong to have to couple queue plugins to concrete queues. IMHO separating the configuration step from the queue plugin itself is exactly how it was designed to work.

Anonymous’s picture

My use case was that I had a specific tasks in a queue in a cloud and specific plugins to process these tasks but switching to that cloud queue backend would switch all Drupal tasks which was not what I wanted. I wanted to keep the Drupal stuff in local db backend but these specific tasks outside in remote queue.

dawehner’s picture

Isn't that the reason why you can have different queue configurations? 'queue_service_' . $name

Anonymous’s picture

Yes, but the point of this issue is to define this in the queue worker plugin, not in the settings.php.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.0-alpha1 will be released the week of July 31, 2017, which means new developments and disruptive changes should now be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

malcolm_p’s picture

While I can understand the desire to decouple workers from the backend service. I've also encountered a need to use a custom queue implementation (extending DatabaseQueue). Managing this through settings.php adds some additional integration requirements to other sites using this queue that I don't think should be necessary.

As long as an explicit backend_service is not required I think this would be useful.

dawehner’s picture

It would still be nice to have a issue summary which describes WHY this feature is needed / helpful.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.0-alpha1 will be released the week of January 17, 2018, which means new developments and disruptive changes should now be targeted against the 8.6.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.6.x-dev » 8.7.x-dev

Drupal 8.6.0-alpha1 will be released the week of July 16, 2018, which means new developments and disruptive changes should now be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

andrewbelcher’s picture

I've updated the IS summary with a concrete example, which for my case is process heavy actions on orders, but that need to be reliable run if an order is about to be processed.

bojanz’s picture

In the meantime, I suggest look at/using https://www.drupal.org/project/advancedqueue
It's the Queue API rewrite that we needed to do for our needs in Commerce.

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.

cliddell’s picture

I can second @malcom_p's use case. I recently ran into the same issue of needing to extend DatabaseQueue for a module I'm currently writing, but being unable use the queue service in the module to make use of it.

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.

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

voleger’s picture

Status: Active » Needs review

Introduced the first version of the refactoring. Reviews are welcome.

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.

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.

voleger’s picture

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

Changing target branch to 10.0.x.

andypost’s picture

voleger’s picture

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

Rerolled against 10.1.x

smustgrave’s picture

Status: Needs review » Needs work

Moving to NW for the open threads and suggestions made.

voleger’s picture

Status: Needs work » Needs review

Needs review

smustgrave’s picture

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

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.

Code wise everything looks good
New functions and properties are typehinted
trigger_errors are call where needed

Only issue I see is that the link the trigger_error calls should point a change record that shuld be added to this ticket.

Other then that everything looks good

Good work!

voleger’s picture

Status: Needs work » Needs review
Issue tags: -Needs change record

Added CR https://www.drupal.org/node/3338022 , updated links in PR

smustgrave’s picture

Status: Needs review » Needs work

Thanks! Can you also include in the CR that the QueueFactory now requires QueueWorkerManagerInterface.

Would search for other CR where parameters are added for wording suggestions.

voleger’s picture

Status: Needs work » Needs review

Updated CR.

smustgrave’s picture

Status: Needs review » Reviewed & tested by the community

Think that should be good.

catch’s picture

Status: Reviewed & tested by the community » Needs work

Left some comments on the MR.

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

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

solideogloria’s picture

So instead of having hardcoded variable in settings.php I propose a new attribute is added to the QueueWorker annotation class backend_service. This would default to the current queue.database service if no value would be provided.

The issue summary mentions an annotation class, but that's not how the merge request is solving the problem. Is there a way to use an annotation? Or should the solution continue down the path of a member variable/constant/function?

berdir’s picture

The definition is the annotation and the MR updates the annotation.

This would need to update the attribute class now as well.

I'm not really convinced this is a good idea. I see that there are sometimes use cases where you implement a custom queue plugin and want to use a specific storage at the same time and that currently requires an extra line in settings.php, but I'd argue it's at least as common to use a certain backend for a queue plugin that you didn't implement yourself and this now requires a module with custom code, that might need its own set of environment-specific control to only do that on certain environments. Maybe we support both without deprecating the existing approach, not really a reason to not support both? The cache backend is similar in that cache bins can have a default backend that can be overridden.

voleger’s picture

Settings.php overrides are unsuitable for the modules that try to control the backend of the queue worker.
I like the idea of keeping the current approach to override the backend service.

What if, instead of extending attribute/annotation, we introduce an extension point by dispatching an event right after determining the service name?

voleger’s picture

Status: Needs work » Needs review

Updated CR

berdir’s picture

I still have reservations about this as I said in #38. IMHO, this should only add a new way to configure this and not deprecate the existing settings key.

I understand that there is a use case that specific queues want to default to a specific backend. But it's also a site/infrastructure level question, even for specific bins to move them to a different backend.

IMHO, this should mirror the logic in \Drupal\Core\Cache\CacheFactory::get:

bin/queue setting > bin/queue specific default > global setting > database fallback.

smustgrave’s picture

@berdir thoughts on the latest changes?

ghost of drupal past’s picture

I still do not understand the need from the IS:

A concrete example of where this would be useful is for queue items that process orders (e.g. in commerce). [...] The obvious way to do this is to use a queue backend that stores the order ID in a separate field that can be used to query/filter other queue backend methods (e.g. claimItem).

The code to place an item surely uses a specific queue name and does not look it up based on the queue worker, does it? If that's so then decorate the queue service and return your own backend based on the queue name. The responsibility of the worker is to process an item, why does it care where it came from?

voleger’s picture

At the moment, there is no way to provide a different backend for a specific queue other than setting it in settings.php. I attempted to implement the UI for such a configuration, but ended up with no way to alter those values in the dedicated module implementation. QueueWorkerManager aggregates definitions and also allows definition alteration in info hook implementations. I thought the QueueWorker definition could provide a way to switch the selected backend if a different backend is not set for the queue in settings.php.

ghost of drupal past’s picture

At the moment, there is no way to provide a different backend for a specific queue other than setting it in settings.php.

This is true. I recommend using a queue service decorator for the purpose. Is that not adequate?

voleger’s picture

Yes, it is an option. There is a Queue Order project that provides decoration for QueueWorkerManager for a different reason, so I think decorating QueueFactory should do the backend override.

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.

smustgrave’s picture

Issue tags: +Needs tests

Most likely will need test coverage too.