Commit 83c53707 authored by alexpott's avatar alexpott

Issue #2466585 by Wim Leers, Fabianx: Decouple cache implementation from the...

Issue #2466585 by Wim Leers, Fabianx: Decouple cache implementation from the renderer and expose as renderCache service
parent 8b9dfcef
...@@ -853,7 +853,7 @@ services: ...@@ -853,7 +853,7 @@ services:
- { name: event_subscriber } - { name: event_subscriber }
main_content_renderer.html: main_content_renderer.html:
class: Drupal\Core\Render\MainContent\HtmlRenderer class: Drupal\Core\Render\MainContent\HtmlRenderer
arguments: ['@title_resolver', '@plugin.manager.display_variant', '@event_dispatcher', '@element_info', '@module_handler', '@renderer', '@cache_contexts_manager'] arguments: ['@title_resolver', '@plugin.manager.display_variant', '@event_dispatcher', '@element_info', '@module_handler', '@renderer', '@render_cache', '@cache_contexts_manager']
tags: tags:
- { name: render.main_content_renderer, format: html } - { name: render.main_content_renderer, format: html }
main_content_renderer.ajax: main_content_renderer.ajax:
...@@ -1346,8 +1346,11 @@ services: ...@@ -1346,8 +1346,11 @@ services:
tags: tags:
- { name: mime_type_guesser } - { name: mime_type_guesser }
lazy: true lazy: true
render_cache:
class: Drupal\Core\Render\RenderCache
arguments: ['@request_stack', '@cache_factory', '@cache_contexts_manager']
renderer: renderer:
class: Drupal\Core\Render\Renderer class: Drupal\Core\Render\Renderer
arguments: ['@controller_resolver', '@theme.manager', '@plugin.manager.element_info', '@request_stack', '@cache_factory', '@cache_contexts_manager', '%renderer.config%'] arguments: ['@controller_resolver', '@theme.manager', '@plugin.manager.element_info', '@render_cache', '%renderer.config%']
email.validator: email.validator:
class: Egulias\EmailValidator\EmailValidator class: Egulias\EmailValidator\EmailValidator
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Render\ElementInfoManagerInterface; use Drupal\Core\Render\ElementInfoManagerInterface;
use Drupal\Core\Render\PageDisplayVariantSelectionEvent; use Drupal\Core\Render\PageDisplayVariantSelectionEvent;
use Drupal\Core\Render\Renderer; use Drupal\Core\Render\RenderCacheInterface;
use Drupal\Core\Render\RendererInterface; use Drupal\Core\Render\RendererInterface;
use Drupal\Core\Render\RenderEvents; use Drupal\Core\Render\RenderEvents;
use Drupal\Core\Routing\RouteMatchInterface; use Drupal\Core\Routing\RouteMatchInterface;
...@@ -72,6 +72,13 @@ class HtmlRenderer implements MainContentRendererInterface { ...@@ -72,6 +72,13 @@ class HtmlRenderer implements MainContentRendererInterface {
*/ */
protected $renderer; protected $renderer;
/**
* The render cache service.
*
* @var \Drupal\Core\Render\RenderCacheInterface
*/
protected $renderCache;
/** /**
* The cache contexts manager service. * The cache contexts manager service.
* *
...@@ -94,16 +101,19 @@ class HtmlRenderer implements MainContentRendererInterface { ...@@ -94,16 +101,19 @@ class HtmlRenderer implements MainContentRendererInterface {
* The module handler. * The module handler.
* @param \Drupal\Core\Render\RendererInterface $renderer * @param \Drupal\Core\Render\RendererInterface $renderer
* The renderer service. * The renderer service.
* @param \Drupal\Core\Render\RenderCacheInterface $render_cache
* The render cache service.
* @param \Drupal\Core\Cache\CacheContextsManager $cache_contexts_manager * @param \Drupal\Core\Cache\CacheContextsManager $cache_contexts_manager
* The cache contexts manager service. * The cache contexts manager service.
*/ */
public function __construct(TitleResolverInterface $title_resolver, PluginManagerInterface $display_variant_manager, EventDispatcherInterface $event_dispatcher, ElementInfoManagerInterface $element_info_manager, ModuleHandlerInterface $module_handler, RendererInterface $renderer, CacheContextsManager $cache_contexts_manager) { public function __construct(TitleResolverInterface $title_resolver, PluginManagerInterface $display_variant_manager, EventDispatcherInterface $event_dispatcher, ElementInfoManagerInterface $element_info_manager, ModuleHandlerInterface $module_handler, RendererInterface $renderer, RenderCacheInterface $render_cache, CacheContextsManager $cache_contexts_manager) {
$this->titleResolver = $title_resolver; $this->titleResolver = $title_resolver;
$this->displayVariantManager = $display_variant_manager; $this->displayVariantManager = $display_variant_manager;
$this->eventDispatcher = $event_dispatcher; $this->eventDispatcher = $event_dispatcher;
$this->elementInfoManager = $element_info_manager; $this->elementInfoManager = $element_info_manager;
$this->moduleHandler = $module_handler; $this->moduleHandler = $module_handler;
$this->renderer = $renderer; $this->renderer = $renderer;
$this->renderCache = $render_cache;
$this->cacheContextsManager = $cache_contexts_manager; $this->cacheContextsManager = $cache_contexts_manager;
} }
...@@ -217,7 +227,7 @@ protected function prepare(array $main_content, Request $request, RouteMatchInte ...@@ -217,7 +227,7 @@ protected function prepare(array $main_content, Request $request, RouteMatchInte
// @todo Remove this once https://www.drupal.org/node/2359901 lands. // @todo Remove this once https://www.drupal.org/node/2359901 lands.
if (!empty($main_content)) { if (!empty($main_content)) {
$this->renderer->render($main_content, FALSE); $this->renderer->render($main_content, FALSE);
$main_content = $this->renderer->getCacheableRenderArray($main_content) + [ $main_content = $this->renderCache->getCacheableRenderArray($main_content) + [
'#title' => isset($main_content['#title']) ? $main_content['#title'] : NULL '#title' => isset($main_content['#title']) ? $main_content['#title'] : NULL
]; ];
} }
......
This diff is collapsed.
<?php
/**
* @file
* Contains \Drupal\Core\Render\RenderCacheInterface.
*/
namespace Drupal\Core\Render;
/**
* Defines an interface for caching rendered render arrays.
*
* @see sec_caching
*
* @see \Drupal\Core\Render\RendererInterface
*/
interface RenderCacheInterface {
/**
* Gets a cacheable render array for a render array and its rendered output.
*
* Given a render array and its rendered output (HTML string), return an array
* data structure that allows the render array and its associated metadata to
* be cached reliably (and is serialization-safe).
*
* If Drupal needs additional rendering metadata to be cached at some point,
* consumers of this method will continue to work. Those who only cache
* certain parts of a render array will cease to work.
*
* @param array $elements
* A render array, on which \Drupal\Core\Render\RendererInterface::render()
* has already been invoked.
*
* @return array
* An array representing the cacheable data for this render array.
*/
public function getCacheableRenderArray(array $elements);
/**
* Gets the cached, pre-rendered element of a renderable element from cache.
*
* @param array $elements
* A renderable array.
*
* @return array
* A renderable array, with the original element and all its children pre-
* rendered, or FALSE if no cached copy of the element is available.
*
* @see \Drupal\Core\Render\RendererInterface::render()
* @see ::set()
*/
public function get(array $elements);
/**
* Caches the rendered output of a renderable array.
*
* May be called by an implementation of \Drupal\Core\Render\RendererInterface
* while rendering, if the #cache property is set.
*
* @param array $elements
* A renderable array.
* @param array $pre_bubbling_elements
* A renderable array corresponding to the state (in particular, the
* cacheability metadata) of $elements prior to the beginning of its
* rendering process, and therefore before any bubbling of child
* information has taken place. Only the #cache property is used by this
* function, so the caller may omit all other properties and children from
* this array.
*
* @return bool|null
* Returns FALSE if no cache item could be created, NULL otherwise.
*
* @see ::get()
*/
public function set(array &$elements, array $pre_bubbling_elements);
}
This diff is collapsed.
...@@ -308,25 +308,6 @@ public function renderPlain(&$elements); ...@@ -308,25 +308,6 @@ public function renderPlain(&$elements);
*/ */
public function render(&$elements, $is_root_call = FALSE); public function render(&$elements, $is_root_call = FALSE);
/**
* Gets a cacheable render array for a render array and its rendered output.
*
* Given a render array and its rendered output (HTML string), return an array
* data structure that allows the render array and its associated metadata to
* be cached reliably (and is serialization-safe).
*
* If Drupal needs additional rendering metadata to be cached at some point,
* consumers of this method will continue to work. Those who only cache
* certain parts of a render array will cease to work.
*
* @param array $elements
* A renderable array, on which ::render() has already been invoked.
*
* @return array
* An array representing the cacheable data for this render array.
*/
public function getCacheableRenderArray(array $elements);
/** /**
* Merges the bubbleable rendering metadata o/t 2nd render array with the 1st. * Merges the bubbleable rendering metadata o/t 2nd render array with the 1st.
* *
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
namespace Drupal\views\Plugin\views\cache; namespace Drupal\views\Plugin\views\cache;
use Drupal\Core\Cache\Cache; use Drupal\Core\Cache\Cache;
use Drupal\Core\Render\RenderCacheInterface;
use Drupal\Core\Render\RendererInterface; use Drupal\Core\Render\RendererInterface;
use Drupal\views\Plugin\views\PluginBase; use Drupal\views\Plugin\views\PluginBase;
use Drupal\Core\Database\Query\Select; use Drupal\Core\Database\Query\Select;
...@@ -80,6 +81,13 @@ abstract class CachePluginBase extends PluginBase { ...@@ -80,6 +81,13 @@ abstract class CachePluginBase extends PluginBase {
*/ */
protected $renderer; protected $renderer;
/**
* The render cache service.
*
* @var \Drupal\Core\Render\RenderCacheInterface
*/
protected $renderCache;
/** /**
* Constructs a CachePluginBase object. * Constructs a CachePluginBase object.
* *
...@@ -91,11 +99,14 @@ abstract class CachePluginBase extends PluginBase { ...@@ -91,11 +99,14 @@ abstract class CachePluginBase extends PluginBase {
* The plugin implementation definition. * The plugin implementation definition.
* @param \Drupal\Core\Render\RendererInterface $renderer * @param \Drupal\Core\Render\RendererInterface $renderer
* The HTML renderer. * The HTML renderer.
* @param \Drupal\Core\Render\RenderCacheInterface $render_cache
* The render cache service.
*/ */
public function __construct(array $configuration, $plugin_id, $plugin_definition, RendererInterface $renderer) { public function __construct(array $configuration, $plugin_id, $plugin_definition, RendererInterface $renderer, RenderCacheInterface $render_cache) {
parent::__construct($configuration, $plugin_id, $plugin_definition); parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->renderer = $renderer; $this->renderer = $renderer;
$this->renderCache = $render_cache;
} }
/** /**
...@@ -106,7 +117,8 @@ public static function create(ContainerInterface $container, array $configuratio ...@@ -106,7 +117,8 @@ public static function create(ContainerInterface $container, array $configuratio
$configuration, $configuration,
$plugin_id, $plugin_id,
$plugin_definition, $plugin_definition,
$container->get('renderer') $container->get('renderer'),
$container->get('render_cache')
); );
} }
...@@ -190,7 +202,7 @@ public function cacheSet($type) { ...@@ -190,7 +202,7 @@ public function cacheSet($type) {
// Also assign the cacheable render array back to the display handler so // Also assign the cacheable render array back to the display handler so
// that is used to render the view for this request and rendering does // that is used to render the view for this request and rendering does
// not happen twice. // not happen twice.
$this->storage = $this->view->display_handler->output = $this->renderer->getCacheableRenderArray($output); $this->storage = $this->view->display_handler->output = $this->renderCache->getCacheableRenderArray($output);
\Drupal::cache($this->outputBin)->set($this->generateOutputKey(), $this->storage, $this->cacheSetExpire($type), Cache::mergeTags($this->storage['#cache']['tags'], ['rendered'])); \Drupal::cache($this->outputBin)->set($this->generateOutputKey(), $this->storage, $this->cacheSetExpire($type), Cache::mergeTags($this->storage['#cache']['tags'], ['rendered']));
break; break;
} }
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
use Drupal\Core\Datetime\DateFormatter; use Drupal\Core\Datetime\DateFormatter;
use Drupal\Core\Cache\Cache; use Drupal\Core\Cache\Cache;
use Drupal\Core\Render\RenderCacheInterface;
use Drupal\Core\Render\RendererInterface; use Drupal\Core\Render\RendererInterface;
use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Form\FormStateInterface;
...@@ -51,10 +52,12 @@ class Time extends CachePluginBase { ...@@ -51,10 +52,12 @@ class Time extends CachePluginBase {
* The HTML renderer. * The HTML renderer.
* @param \Drupal\Core\Datetime\DateFormatter $date_formatter * @param \Drupal\Core\Datetime\DateFormatter $date_formatter
* The date formatter service. * The date formatter service.
* @param \Drupal\Core\Render\RenderCacheInterface $render_cache
* The render cache service.
*/ */
public function __construct(array $configuration, $plugin_id, $plugin_definition, RendererInterface $renderer, DateFormatter $date_formatter) { public function __construct(array $configuration, $plugin_id, $plugin_definition, RendererInterface $renderer, RenderCacheInterface $render_cache, DateFormatter $date_formatter) {
$this->dateFormatter = $date_formatter; $this->dateFormatter = $date_formatter;
parent::__construct($configuration, $plugin_id, $plugin_definition, $renderer); parent::__construct($configuration, $plugin_id, $plugin_definition, $renderer, $render_cache);
} }
/** /**
...@@ -66,6 +69,7 @@ public static function create(ContainerInterface $container, array $configuratio ...@@ -66,6 +69,7 @@ public static function create(ContainerInterface $container, array $configuratio
$plugin_id, $plugin_id,
$plugin_definition, $plugin_definition,
$container->get('renderer'), $container->get('renderer'),
$container->get('render_cache'),
$container->get('date.formatter') $container->get('date.formatter')
); );
} }
......
...@@ -71,9 +71,9 @@ public function testPostRenderCacheWithCacheDisabled() { ...@@ -71,9 +71,9 @@ public function testPostRenderCacheWithCacheDisabled() {
/** /**
* @covers ::render * @covers ::render
* @covers ::doRender * @covers ::doRender
* @covers ::cacheGet * @covers \Drupal\Core\Render\RenderCache::get
* @covers ::cacheSet * @covers \Drupal\Core\Render\RenderCache::set
* @covers ::createCacheID * @covers \Drupal\Core\Render\RenderCache::createCacheID
*/ */
public function testPostRenderCacheWithColdCache() { public function testPostRenderCacheWithColdCache() {
list($test_element, $context) = $this->generatePostRenderCacheElement(); list($test_element, $context) = $this->generatePostRenderCacheElement();
...@@ -127,7 +127,7 @@ public function testPostRenderCacheWithColdCache() { ...@@ -127,7 +127,7 @@ public function testPostRenderCacheWithColdCache() {
/** /**
* @covers ::render * @covers ::render
* @covers ::doRender * @covers ::doRender
* @covers ::cacheGet * @covers \Drupal\Core\Render\RenderCache::get
* @covers ::processPostRenderCache * @covers ::processPostRenderCache
*/ */
public function testPostRenderCacheWithPostRequest() { public function testPostRenderCacheWithPostRequest() {
...@@ -189,7 +189,7 @@ public function testRenderRecursivePostRenderCache() { ...@@ -189,7 +189,7 @@ public function testRenderRecursivePostRenderCache() {
* *
* @covers ::render * @covers ::render
* @covers ::doRender * @covers ::doRender
* @covers ::cacheGet * @covers \Drupal\Core\Render\RenderCache::get
* @covers ::processPostRenderCache * @covers ::processPostRenderCache
*/ */
public function testRenderChildrenPostRenderCacheDifferentContexts() { public function testRenderChildrenPostRenderCacheDifferentContexts() {
...@@ -284,7 +284,7 @@ public function testRenderChildrenPostRenderCacheDifferentContexts() { ...@@ -284,7 +284,7 @@ public function testRenderChildrenPostRenderCacheDifferentContexts() {
* *
* @covers ::render * @covers ::render
* @covers ::doRender * @covers ::doRender
* @covers ::cacheGet * @covers \Drupal\Core\Render\RenderCache::get
* @covers ::processPostRenderCache * @covers ::processPostRenderCache
*/ */
public function testRenderChildrenPostRenderCacheComplex() { public function testRenderChildrenPostRenderCacheComplex() {
...@@ -404,7 +404,7 @@ public function testRenderChildrenPostRenderCacheComplex() { ...@@ -404,7 +404,7 @@ public function testRenderChildrenPostRenderCacheComplex() {
* *
* @covers ::render * @covers ::render
* @covers ::doRender * @covers ::doRender
* @covers ::cacheGet * @covers \Drupal\Core\Render\RenderCache::get
* @covers ::processPostRenderCache * @covers ::processPostRenderCache
* @covers ::generateCachePlaceholder * @covers ::generateCachePlaceholder
*/ */
......
...@@ -531,9 +531,9 @@ public function testRenderWithThemeArguments() { ...@@ -531,9 +531,9 @@ public function testRenderWithThemeArguments() {
/** /**
* @covers ::render * @covers ::render
* @covers ::doRender * @covers ::doRender
* @covers ::cacheGet * @covers \Drupal\Core\Render\RenderCache::get
* @covers ::cacheSet * @covers \Drupal\Core\Render\RenderCache::set
* @covers ::createCacheID * @covers \Drupal\Core\Render\RenderCache::createCacheID
*/ */
public function testRenderCache() { public function testRenderCache() {
$this->setUpRequest(); $this->setUpRequest();
...@@ -584,9 +584,9 @@ public function testRenderCache() { ...@@ -584,9 +584,9 @@ public function testRenderCache() {
/** /**
* @covers ::render * @covers ::render
* @covers ::doRender * @covers ::doRender
* @covers ::cacheGet * @covers \Drupal\Core\Render\RenderCache::get
* @covers ::cacheSet * @covers \Drupal\Core\Render\RenderCache::set
* @covers ::createCacheID * @covers \Drupal\Core\Render\RenderCache::createCacheID
* *
* @dataProvider providerTestRenderCacheMaxAge * @dataProvider providerTestRenderCacheMaxAge
*/ */
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
use Drupal\Core\Language\LanguageInterface; use Drupal\Core\Language\LanguageInterface;
use Drupal\Core\Render\Element; use Drupal\Core\Render\Element;
use Drupal\Core\Render\Renderer; use Drupal\Core\Render\Renderer;
use Drupal\Core\Render\RenderCache;
use Drupal\Tests\UnitTestCase; use Drupal\Tests\UnitTestCase;
use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
...@@ -29,6 +30,13 @@ class RendererTestBase extends UnitTestCase { ...@@ -29,6 +30,13 @@ class RendererTestBase extends UnitTestCase {
*/ */
protected $renderer; protected $renderer;
/**
* The tested render cache.
*
* @var \Drupal\Core\Render\RenderCache
*/
protected $renderCache;
/** /**
* @var \Symfony\Component\HttpFoundation\RequestStack * @var \Symfony\Component\HttpFoundation\RequestStack
*/ */
...@@ -118,10 +126,12 @@ protected function setUp() { ...@@ -118,10 +126,12 @@ protected function setUp() {
} }
return $keys; return $keys;
}); });
$this->renderer = new Renderer($this->controllerResolver, $this->themeManager, $this->elementInfo, $this->requestStack, $this->cacheFactory, $this->cacheContextsManager, $this->rendererConfig); $this->renderCache = new RenderCache($this->requestStack, $this->cacheFactory, $this->cacheContextsManager);
$this->renderer = new Renderer($this->controllerResolver, $this->themeManager, $this->elementInfo, $this->renderCache, $this->rendererConfig);
$container = new ContainerBuilder(); $container = new ContainerBuilder();
$container->set('cache_contexts_manager', $this->cacheContextsManager); $container->set('cache_contexts_manager', $this->cacheContextsManager);
$container->set('render_cache', $this->renderCache);
$container->set('renderer', $this->renderer); $container->set('renderer', $this->renderer);
\Drupal::setContainer($container); \Drupal::setContainer($container);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment