diff --git a/core/lib/Drupal/Core/DrupalKernel.php b/core/lib/Drupal/Core/DrupalKernel.php index b8eeb4f365fb..82afbaaea8a0 100644 --- a/core/lib/Drupal/Core/DrupalKernel.php +++ b/core/lib/Drupal/Core/DrupalKernel.php @@ -712,7 +712,7 @@ class DrupalKernel implements DrupalKernelInterface, TerminableInterface { * The class name. */ protected function getClassName() { - $parts = array('service_container', $this->environment); + $parts = array('service_container', $this->environment, hash('crc32b', \Drupal::VERSION . Settings::get('deployment_identifier'))); return implode('_', $parts); } diff --git a/core/modules/system/src/Tests/DrupalKernel/ContainerRebuildWebTest.php b/core/modules/system/src/Tests/DrupalKernel/ContainerRebuildWebTest.php new file mode 100644 index 000000000000..734328d640a7 --- /dev/null +++ b/core/modules/system/src/Tests/DrupalKernel/ContainerRebuildWebTest.php @@ -0,0 +1,38 @@ +drupalGet(''); + $this->assertHeader('container_rebuild_indicator', FALSE); + + $this->writeSettings(['settings' => ['deployment_identifier' => (object) ['value' => 'new-identifier', 'required' => TRUE]]]); + + $this->drupalGet(''); + + $this->assertHeader('container_rebuild_indicator', 'new-identifier'); + } + +} diff --git a/core/modules/system/tests/modules/service_provider_test/service_provider_test.services.yml b/core/modules/system/tests/modules/service_provider_test/service_provider_test.services.yml index dda70f599622..77e13dd9268c 100644 --- a/core/modules/system/tests/modules/service_provider_test/service_provider_test.services.yml +++ b/core/modules/system/tests/modules/service_provider_test/service_provider_test.services.yml @@ -4,4 +4,5 @@ services: tags: - { name: event_subscriber } - { name: needs_destruction } + parent: container.trait arguments: ['@state'] diff --git a/core/modules/system/tests/modules/service_provider_test/src/ServiceProviderTestServiceProvider.php b/core/modules/system/tests/modules/service_provider_test/src/ServiceProviderTestServiceProvider.php index c3b14b34b9e2..9759e2c80bd5 100644 --- a/core/modules/system/tests/modules/service_provider_test/src/ServiceProviderTestServiceProvider.php +++ b/core/modules/system/tests/modules/service_provider_test/src/ServiceProviderTestServiceProvider.php @@ -9,6 +9,7 @@ namespace Drupal\service_provider_test; use Drupal\Core\DependencyInjection\ContainerBuilder; use Drupal\Core\DependencyInjection\ServiceModifierInterface; +use Drupal\Core\Site\Settings; class ServiceProviderTestServiceProvider implements ServiceModifierInterface { @@ -21,5 +22,9 @@ class ServiceProviderTestServiceProvider implements ServiceModifierInterface { $definition = $container->getDefinition('file.usage'); $definition->setClass('Drupal\service_provider_test\TestFileUsage'); } + + if ($indicator = Settings::get('deployment_identifier')) { + $container->setParameter('container_rebuild_indicator', $indicator); + } } } diff --git a/core/modules/system/tests/modules/service_provider_test/src/TestClass.php b/core/modules/system/tests/modules/service_provider_test/src/TestClass.php index e46accd04f89..a651ae8ed52e 100644 --- a/core/modules/system/tests/modules/service_provider_test/src/TestClass.php +++ b/core/modules/system/tests/modules/service_provider_test/src/TestClass.php @@ -9,11 +9,16 @@ namespace Drupal\service_provider_test; use Drupal\Core\State\StateInterface; use Drupal\Core\DestructableInterface; +use Symfony\Component\DependencyInjection\ContainerAwareInterface; +use Symfony\Component\DependencyInjection\ContainerAwareTrait; use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Symfony\Component\HttpKernel\Event\FilterResponseEvent; use Symfony\Component\HttpKernel\Event\GetResponseEvent; use Symfony\Component\HttpKernel\KernelEvents; -class TestClass implements EventSubscriberInterface, DestructableInterface { +class TestClass implements EventSubscriberInterface, DestructableInterface, ContainerAwareInterface { + + use ContainerAwareTrait; /** * The state keyvalue collection. @@ -39,6 +44,15 @@ class TestClass implements EventSubscriberInterface, DestructableInterface { drupal_set_message(t('The service_provider_test event subscriber fired!')); } + /** + * Flags the response in case a rebuild indicator is used. + */ + public function onKernelResponseTest(FilterResponseEvent $event) { + if ($this->container->hasParameter('container_rebuild_indicator')) { + $event->getResponse()->headers->set('container_rebuild_indicator', $this->container->getParameter('container_rebuild_indicator')); + } + } + /** * Registers methods as kernel listeners. * @@ -47,6 +61,7 @@ class TestClass implements EventSubscriberInterface, DestructableInterface { */ static function getSubscribedEvents() { $events[KernelEvents::REQUEST][] = array('onKernelRequestTest'); + $events[KernelEvents::RESPONSE][] = array('onKernelResponseTest'); return $events; } diff --git a/sites/default/default.settings.php b/sites/default/default.settings.php index 4c2dfbd00456..330cc560e8b3 100644 --- a/sites/default/default.settings.php +++ b/sites/default/default.settings.php @@ -286,6 +286,16 @@ $config_directories = array(); */ $settings['hash_salt'] = ''; +/** + * Deployment identifier. + * + * Drupal's dependency injection container will be automatically invalidated and + * rebuilt when the Drupal core version changes. When updating contributed or + * custom code that changes the container, changing this identifier will also + * allow the container to be invalidated as soon as code is deployed. + */ +# $settings['deployment_identifier'] = \Drupal::VERSION; + /** * Access control for update.php script. *