diff -u b/core/modules/history/history.services.yml b/core/modules/history/history.services.yml --- b/core/modules/history/history.services.yml +++ b/core/modules/history/history.services.yml @@ -2,5 +2,5 @@ history.repository: class: Drupal\history\HistoryRepository - arguments: ['@database', '@datetime.time'] + arguments: ['@database', '@datetime.time', '@entity.memory_cache'] tags: - { name: backend_overridable } diff -u b/core/modules/history/src/HistoryRepository.php b/core/modules/history/src/HistoryRepository.php --- b/core/modules/history/src/HistoryRepository.php +++ b/core/modules/history/src/HistoryRepository.php @@ -1,10 +1,5 @@ connection = $connection; $this->time = $time; + $this->memoryCache = $memory_cache; } /** * {@inheritdoc} */ - public function getLastViewed($entity_type, $entity_ids, AccountInterface $account) { + public function getLastViewed($entity_type, array $entity_ids, AccountInterface $account) { $entities = []; - $entities_to_read = []; foreach ($entity_ids as $entity_id) { - if (isset($this->history[$entity_type][$account->id()][$entity_id])) { - $entities[$entity_id] = $this->history[$entity_type][$account->id()][$entity_id]; + // Get cache. + $cache = $this->memoryCache->get( + $this->buildCacheId($account->id(), $entity_type, $entity_id + )); + if ($cache) { + $entities[$entity_id] = $cache; } else { $entities_to_read[$entity_id] = 0; @@ -84,12 +94,15 @@ ->execute(); foreach ($result as $row) { - $entities_to_read[$row->entity_id] = (int) $row->timestamp; - } - if (!isset($this->history[$entity_type][$account->id()])) { - $this->history[$entity_type][$account->id()] = []; + $timestamp = (int) $row->timestamp; + $this->memoryCache->set( + $this->buildCacheId($account->id(), $entity_type, $row->entity_id), + $timestamp, + Cache::PERMANENT, + $this->getCacheTags($account->id(), $row->entity_id) + ); + $entities_to_read[$row->entity_id] = $timestamp; } - $this->history[$entity_type][$account->id()] += $entities_to_read; return $entities + $entities_to_read; } @@ -108,11 +121,43 @@ ->fields(['timestamp' => $this->time->getRequestTime()]) ->execute(); // Update cached value. - $this->history[$entity->getEntityTypeId()][$account->id()][$entity->id()] = $this->time->getRequestTime(); + $this->memoryCache->set( + $this->buildCacheId($account->id(), $entity->getEntityTypeId(), $entity->id()), + $this->time->getRequestTime(), Cache::PERMANENT, + $this->getCacheTags($account->id(), $entity->id()) + ); } } /** + * Builds the cache ID for the history timestamp. + * + * @param int $uid + * The User ID. + * @param string $entity_type + * The entity type. + * @param int $entity_id + * The entity ID. + * + * @return string + * Cache ID that can be passed to the cache backend. + */ + protected function buildCacheId($uid, $entity_type, $entity_id) { + return implode(':', ['history', $uid, $entity_type, $entity_id]); + } + + /** + * {@inheritdoc} + */ + public function getCacheTags($uid, $entity_id) { + return [ + 'history', + "history:user:{$uid}", + "history:entity:{$entity_id}", + ]; + } + + /** * {@inheritdoc} */ public function purge() { @@ -120,7 +165,7 @@ ->condition('timestamp', HISTORY_READ_LIMIT, '<') ->execute(); // Clean static cache. - $this->resetCache(); + Cache::invalidateTags(['history']); } /** @@ -131,7 +176,7 @@ ->condition('uid', $account->id()) ->execute(); // Clean static cache. - $this->resetCache(); + Cache::invalidateTags(["history:user:{$account->id()}"]); } /** @@ -143,33 +188,7 @@ ->condition('entity_type', $entity->getEntityTypeId()) ->execute(); // Clean static cache. - $this->resetCache(); - } - - /** - * {@inheritdoc} - */ - public function resetCache() { - $this->history = []; - } - - /** - * {@inheritdoc} - */ - public function __sleep() { - $vars = $this->defaultSleep(); - // Do not serialize static cache. - unset($vars['history']); - return $vars; - } - - /** - * {@inheritdoc} - */ - public function __wakeup() { - $this->defaultWakeup(); - // Initialize static cache. - $this->history = []; + Cache::invalidateTags(["history:entity:{$entity->id()}"]); } } diff -u b/core/modules/history/src/HistoryRepositoryInterface.php b/core/modules/history/src/HistoryRepositoryInterface.php --- b/core/modules/history/src/HistoryRepositoryInterface.php +++ b/core/modules/history/src/HistoryRepositoryInterface.php @@ -30,7 +30,7 @@ * viewed by the user, the timestamp in seconds of when the last view * occurred; otherwise, zero. */ - public function getLastViewed($entity_type, $entity_ids, AccountInterface $account); + public function getLastViewed($entity_type, array $entity_ids, AccountInterface $account); /** * Updates 'last viewed' timestamp of the entity for the user account. @@ -43,6 +43,19 @@ public function updateLastViewed(EntityInterface $entity, AccountInterface $account); /** + * Gets an array of cache tags for the history timestamp. + * + * @param int $uid + * The User ID. + * @param int $entity_id + * The entity ID. + * + * @return string[] + * An array of cache tags based on the current view. + */ + public function getCacheTags($uid, $entity_id); + + /** * Purges outdated history. */ public function purge();