The ConfigFactory class has a simple static cache that keeps track of the Config objects that it handles. This static cache does not have awareness of the cacheability metadata of the items it holds. When for example some of its items have their cache tags invalidated these are not removed from the cache, and the ConfigFactory will return stale items.

We can fix this by replacing the simple static cache with a @cache.static memory backend.

Issue fork drupal-3063687

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

pfrenssen created an issue. See original summary.

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.

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.

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.

mikeryan’s picture

#3304778: Missing required data for configuration: x reports the visible consequences of this issue - since that has more conversation, should we close this one in favor of that?

mikeryan’s picture

StatusFileSize
new7.84 KB

Well, I have a POC for this issue, but (so far) it doesn't fix the config import issue of #3304778: Missing required data for configuration: x. I won't be able to work on this for the next week, so I figured I'd upload the patch, let the testbots make sure it at least doesn't break anything, and start a conversation about how to cleanly use a proper memory cache in ConfigFactory.

Notes:

  1. Of course, the cache backend should be properly injected, which means an API change (new parameter to ConfigFactory::__construct()).
  2. code.static doesn't work, because it serializes the config objects. Using MemoryCache instead.
  3. ConfigFactory::getConfigCacheKeys() searches its cache's keys, which is... not a thing for our cache classes. For now, I created a SearchableMemoryCache class to hold getConfigCacheKeys()
  4. If this works as it should, I think we should be able to remove ConfigFactory::onConfigSave().

A larger question is - does ConfigFactory really need its own cache at all? In practice, the storage it's passed should usually if not always be CachedStorage - is it for getConfigCacheKeys(), and if so can we find a different way to accomplish that? Actually, looking more closely at where that's used - it seems to be about managing the internal cache, so doesn't seem necessary if we're using a real cache implementation?

mikeryan’s picture

Status: Active » Needs review
mikeryan’s picture

Status: Needs review » Needs work

I'm mildly surprised nothing broke (at least nothing being currently tested)... But this definitely is not the answer as-is...

mikeryan’s picture

Deshna Chauhan’s picture

StatusFileSize
new6.73 KB

Added patch against #14 in 10.1.x version.

bnjmnm’s picture

Ignore #14 and base additional work on #10

@Deshna Chauhan There are several things incorrect with your patch in #14

  1. A patch was not needed - the patch in #10 applies to 10.1.x just fine, we can see that from the green test results
  2. The version you supplied excludes one of the files entirely, it's removing other people's work and effectively breaking the patch. This is very disruptive as people will often assume the most recent patch is the one to build from.
  3. Patches should have the .patch file extension. In this case it's was good that it didn't, since this particular patch discards important work from the prior patch, but that's the usual naming convention

I've seen similar patch problems with a few contributors from Dotsquares. If anyone from that company would like guidance on finding issues that legitimately need rerolls, and how to do the rerolls properly, have them find me on Drupal Slack and I'm happy to help.

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.

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

bhanu951’s picture

Rerolled patch from #10 against 11.x branch, added deprecation error message to constructor .

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

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.

kristiaanvandeneynde’s picture

Since this issue was created, we've had some changes to memory caches, meaning they are now officially supported and you can easily define your own bin. Given how many config objects a Drupal site tends to have, I would definitely consider a dedicated bin here. Example:

  cache.config_factory_memory:
    class: Drupal\Core\Cache\CacheBackendInterface
    tags:
      - { name: cache.bin.memory, default_backend: cache.backend.memory.memory }
    factory: ['@cache_factory', 'get']
    arguments: [config_factory_memory]

We can then add a #[Autowire(service: 'cache.config_factory_memory')] attribute to suggest our service to be autowired as the memory cache.

I just had an obscure bug myself that was in part caused by this issue, so we should definitely update the static property to a memory cache. However, while the goal of the current MR's SearchableMemoryCache is obvious, I'm not sure we can or should pull that off here.

I mean, we could bypass the cache factory which is fed all backends tagged with "cache.bin.memory" (see ListCacheBinsPass) and then uses its default backend (MemoryCacheFactory) in CacheFactory. We could do that by creating our own factory, set that in the "default_backend" tag in the code example above and that would work and return a SearchableMemoryCache, which extends MemoryCache.

But the question is if we should. Because we'd still be type-hinting for CacheBackendInterface and getConfigCacheKeys or, better yet, asking which cache keys a cache has is not part of that interface. So perhaps we should make that part of the CacheBackendInterface instead and use that here.

E.g.: CacheBackendInterface::getCids()


Edit:
Then again, the list of CIDs would only be worth it on caches that instantly invalidate their items. E.g.: DB caches use checksums so could contain CIDs that are no longer valid. At that point the question becomes what use there is in querying the list of CIDS.

So maybe we can park the bigger picture for now and add the functionality to an extension of MemoryCacheInterface instead and typehint that? We can't add it to MemoryCacheInterface itself because there are contrib modules out there that implement said interface directly (wse_config jumps to mind).