Unnecessary loading of configuration entities when ID is not the first condition in a config entity query

Created on 21 September 2021, over 3 years ago
Updated 29 August 2023, over 1 year ago

Problem/Motivation

We recently discovered that the configuration for all webforms on our site was being loaded and experiencing OOM issues as a result. The load of the configuration was being triggered by the validation handler for the webform submission. The validation handler is responsible for validating the entity reference from the webform submission back to the webform and it does this by perform a config entity query. When the config entity query is executed it initially loads the records using the conditions to filter the records. This is where the problem lies - this function seemingly assumes a condition referencing the id key to be the first condition in order to maximise efficiency and break at the earliest point. However In our case (webforms) there was a condition referencing the id key, but it wasn't the first which meant it eventually fell back to loading all records.

@see \Drupal\Core\Config\Entity\Query\Query::loadRecords

Steps to reproduce

Proposed resolution

Ensure the conditions are sorted with any condition referencing the id key being the first.

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

πŸ› Bug report
Status

Needs work

Version

11.0 πŸ”₯

Component
Configuration entityΒ  β†’

Last updated 3 days ago

Created by

πŸ‡¦πŸ‡ΊAustralia mortim07

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • πŸ‡ΊπŸ‡ΈUnited States smustgrave

    triggering for D10

  • Status changed to RTBC almost 2 years ago
  • πŸ‡ΊπŸ‡ΈUnited States smustgrave

    Passed D10
    Confirmed the tests fail without the fix

    Some predictions failed:
    Double\ConfigFactoryInterface\P1:
      No calls have been made that match:
          Double\ConfigFactoryInterface\P1->loadMultiple(exact(["config_test.dynamic.1"]))
        but expected at least one.
        Recorded `loadMultiple(...)` calls:
          - loadMultiple(["config_test.dynamic.1", "config_test.dynamic.2"]) @ core/lib/Drupal/Core/Config/Entity/Query/Query.php:222
      No calls expected that match:
          Double\ConfigFactoryInterface\P1->loadMultiple(exact(["config_test.dynamic.1", "config_test.dynamic.2"]))
        but 1 was made:
          - loadMultiple(["config_test.dynamic.1", "config_test.dynamic.2"]) @ core/lib/Drupal/Core/Config/Entity/Query/Query.php:222
    

    Looks good

  • Status changed to Needs work almost 2 years ago
  • πŸ‡¬πŸ‡§United Kingdom catch
    +++ b/core/lib/Drupal/Core/Config/Entity/Query/Query.php
    @@ -135,6 +135,11 @@ protected function loadRecords() {
           $conditions = $this->condition->conditions();
    +      usort($conditions, function ($a, $b) use ($id_key) {
    +        $a_score = ($a['field'] == $id_key) ? 1 : 0;
    +        $b_score = ($b['field'] == $id_key) ? 1 : 0;
    +        return $b_score - $a_score;
    +      });
    

    This needs an explanation as to why we're doing the sort. The test coverage will help us not to break it, but I still can't work out why we'd do this just reading the code.

    I also wonder a bit - if the ID key can only appear once in conditions, do we actually need to sort, or could we find it and move its position in the array explicitly?

  • πŸ‡¦πŸ‡ΊAustralia gordon Melbourne

    Rebase patch against 10.1

Production build 0.71.5 2024