diff --git a/core/lib/Drupal/Core/Cache/DatabaseBackend.php b/core/lib/Drupal/Core/Cache/DatabaseBackend.php index d0d8278..3a9fb78 100644 --- a/core/lib/Drupal/Core/Cache/DatabaseBackend.php +++ b/core/lib/Drupal/Core/Cache/DatabaseBackend.php @@ -160,7 +160,9 @@ protected function prepareItem($cache, $allow_invalid) { * Implements Drupal\Core\Cache\CacheBackendInterface::set(). */ public function set($cid, $data, $expire = Cache::PERMANENT, array $tags = array()) { - // Check if maximum expiration settings for cache bin is defined + // Check if maximum expiration settings for cache bin is defined. If set, + // enforce an upper limit for the expiration to allow for garbage + // collection. if (isset($this->configuration['max_expire']) && ($expire == Cache::PERMANENT || $expire > $this->configuration['max_expire'] + REQUEST_TIME)) { $expire = $this->configuration['max_expire'] + REQUEST_TIME; } diff --git a/core/lib/Drupal/Core/Cache/DatabaseBackendFactory.php b/core/lib/Drupal/Core/Cache/DatabaseBackendFactory.php index fd46b66..7b55e51 100644 --- a/core/lib/Drupal/Core/Cache/DatabaseBackendFactory.php +++ b/core/lib/Drupal/Core/Cache/DatabaseBackendFactory.php @@ -44,8 +44,8 @@ class DatabaseBackendFactory implements CacheFactoryInterface { function __construct(Connection $connection, CacheTagsChecksumInterface $checksum_provider) { $this->connection = $connection; $this->checksumProvider = $checksum_provider; - // Set cache_database settings from settings.php and if none is set use - // maximum expire for render bin for one week. + // Load settings and if not set, default to maximum expiration of the render + // cache bin in one week. $this->configuration = Settings::get('cache_database', ['render' => ['max_expire' => 86400 * 7]]); } diff --git a/core/modules/system/src/Tests/Cache/DatabaseBackendUnitTest.php b/core/modules/system/src/Tests/Cache/DatabaseBackendUnitTest.php index a5f8ff7..f88ba11 100644 --- a/core/modules/system/src/Tests/Cache/DatabaseBackendUnitTest.php +++ b/core/modules/system/src/Tests/Cache/DatabaseBackendUnitTest.php @@ -53,23 +53,49 @@ public function testSetGet() { $this->assertIdentical($cached_value_short, $backend->get($cid_short)->data, "Backend contains the correct value for short, non-ASCII cache id."); } - public function testCacheBinExpiration(){ + public function testCacheBinExpiration() { $configuration = ['max_expire' => 2800]; $backend = new DatabaseBackend($this->container->get('database'), $this->container->get('cache_tags.invalidator.checksum'), 'render', $configuration); + $backend->set('test_cache1', 'foo'); $cached = $backend->get('test_cache1'); $this->assertIdentical($cached->expire, (string) (REQUEST_TIME + 2800), 'Maximum cache expire time is correct.'); - $configuration = ['max_expire' => 2800]; - $backend = new DatabaseBackend($this->container->get('database'), $this->container->get('cache_tags.invalidator.checksum'), 'render', $configuration); $backend->set('test_cache2', 'foo', REQUEST_TIME + 2799); $cached = $backend->get('test_cache2'); $this->assertIdentical($cached->expire, (string) (REQUEST_TIME + 2799), 'Maximum cache expire time is correct.'); + $backend->set('test_cache3', 'foo', REQUEST_TIME + 2801); + $cached = $backend->get('test_cache3'); + $this->assertIdentical($cached->expire, (string) (REQUEST_TIME + 2800), 'Maximum cache expire time is not exceeded.'); + } + + public function testCacheBinExpirationSetMultiple() { $configuration = ['max_expire' => 2800]; $backend = new DatabaseBackend($this->container->get('database'), $this->container->get('cache_tags.invalidator.checksum'), 'render', $configuration); - $backend->set('test_cache3', 'foo', REQUEST_TIME + 2801); + + $backend->setMultiple([ + 'test_cache1' => [ + 'data' => 'foo', + ], + 'test_cache2' => [ + 'data' => 'foo', + 'expire' => REQUEST_TIME + 2799, + ], + 'test_cache3' => [ + 'data' => 'foo', + 'expire' => REQUEST_TIME + 2801, + ], + ]); + + $cached = $backend->get('test_cache1'); + $this->assertIdentical($cached->expire, (string) (REQUEST_TIME + 2800), 'Maximum cache expire time is correct.'); + + $cached = $backend->get('test_cache2'); + $this->assertIdentical($cached->expire, (string) (REQUEST_TIME + 2799), 'Maximum cache expire time is correct.'); + $cached = $backend->get('test_cache3'); $this->assertIdentical($cached->expire, (string) (REQUEST_TIME + 2800), 'Maximum cache expire time is not exceeded.'); } + } diff --git a/sites/default/default.settings.php b/sites/default/default.settings.php index b905a11..3777cf0 100644 --- a/sites/default/default.settings.php +++ b/sites/default/default.settings.php @@ -693,9 +693,15 @@ # } /** - * Per-bin database backend configuration - * - * Use this setting to set the maximum cache expiration time for a specific - * cache bin in the database. - */ -$settings['cache_database']['render']['max_expire'] = 86400 * 7; + * Per-bin database backend configuration. + * + * Configure settings for database backend. Available settings are: + * - max_expire: Specify the maximum expiry for an individual cache item in the + * selected bin. Some cache bins can get very big and persistent cache entries + * are never removed. Setting this value will allow them to be garbage + * collected after the configured time, and will need to be rebuilt if the + * item is requested again. + */ +$settings['cache_database']['render'] = [ + 'max_expire' => 86400 * 7, +];