Problem/Motivation

When changing simple configuration with Config UI enabled, it takes a manual cache rebuild to activate the new config

Steps to reproduce

  1. Install domain_config_ui
  2. Configure enabled config forms: system.site: drupal_localhost, two_localhost
  3. Create 2 nodes
  4. Set the frontpage to node/1
  5. Visit the frontpage
  6. Set the frontpage to node/2
  7. Notice the frontpage still renders node 1

Proposed resolution

Invalidate the original cache tags when saving simple configuration

Remaining tasks

  1. Write a merge request
  2. Review
  3. Commit

User interface changes

None

API changes

None

Data model changes

None

Issue fork domain-3575434

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

idebr created an issue. See original summary.

mably’s picture

Status: Active » Postponed (maintainer needs more info)

Hi @idebr, I haven't been able to reproduce the problem locally.

Could you try to provide a test that reproduces your problem?

idebr’s picture

A failing test is available in the merge request

mably’s picture

Thanks @idebr, will have a look at it.

mably’s picture

Status: Postponed (maintainer needs more info) » Needs review

Root cause analysis

When system.site is saved through Drupal's normal admin form, core's \Drupal\system\EventSubscriber\ConfigCacheTag::onSave() listens for ConfigEvents::SAVE and invalidates the route_match and rendered cache tags. This is what causes the RouteProvider's cached route collections to be cleared, so that PathProcessorFront re-resolves / to the new front page path on the next request.

However, when domain config overrides are saved via DomainConfigOverrideEditable::save(), the event dispatched is ConfigCollectionEvents::SAVE_IN_COLLECTIONnot ConfigEvents::SAVE. Core's ConfigCacheTag only subscribes to ConfigEvents::SAVE, so it never sees domain override saves.

The consequence is:

  1. Admin changes the domain front page from /node/1 to /user via the UI
  2. DomainConfigOverrideEditable::save() writes the new value correctly and invalidates config:system.site
  3. On the next request to /, RouteProvider::getRouteCollectionForRequest() finds a cache hit (tagged with route_match, which was not invalidated)
  4. The cached route collection still contains the old resolved path (/node/1)
  5. PathProcessorFront::processInbound() is never called — the RouteProvider skips inbound path processing on cache hit
  6. The old front page is served until a manual cache rebuild

Fix

New event subscriber DomainConfigCacheTag that listens for DomainConfigOverrideEvents::SAVE_OVERRIDE and DELETE_OVERRIDE, and delegates to core's ConfigCacheTag::onSave() by wrapping the domain override in a ConfigCrudEvent. This works because DomainConfigOverride extends Config which extends ConfigBase, so it's compatible with ConfigCrudEvent's constructor.

This way we don't duplicate core's logic — any future changes to ConfigCacheTag::onSave() (e.g. handling additional config names) will automatically apply to domain config overrides too.

Changes

New file: domain_config/src/EventSubscriber/DomainConfigCacheTag.php

class DomainConfigCacheTag implements EventSubscriberInterface {

  public function __construct(
    protected ConfigCacheTag $configCacheTag,
  ) {}

  public function onOverrideChange(DomainConfigOverrideCrudEvent $event) {
    $this->configCacheTag->onSave(
      new ConfigCrudEvent($event->getOverride())
    );
  }

  public static function getSubscribedEvents(): array {
    $events[DomainConfigOverrideEvents::SAVE_OVERRIDE][] = ['onOverrideChange'];
    $events[DomainConfigOverrideEvents::DELETE_OVERRIDE][] = ['onOverrideChange'];
    return $events;
  }

}

Modified: domain_config/domain_config.services.yml — registers the new subscriber with core's system.config_cache_tag service injected.

Modified: domain_config_ui/tests/src/Functional/DomainConfigUIOverrideTest.php — cleaned up and documented testOverrides() with a regression assertion that verifies the front page change takes effect immediately without a manual cache rebuild.

Personal Note: it looks like simply firing ConfigEvents::SAVE could have some undesired side effects.

  • mably committed bf30999a on 3.x
    fix: #3575434 Changing domain config requires a manual cache rebuild to...
mably’s picture

Status: Needs review » Fixed

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.