You are here

function d8cache_do_invalidate_cache_tags in Drupal 8 Cache Backport 7

Perform cache tag invalidations. Must do outside of a transaction.

Throws

\Exception

2 calls to d8cache_do_invalidate_cache_tags()
d8cache_invalidate_cache_tags in ./d8cache.module
Implements hook_invalidate_cache_tags().
d8cache_root_transaction_end in ./d8cache.module
Callback to invalidate cache tags at the end of a transaction.

File

./d8cache.module, line 147
Main module file for the D8 caching system backport.

Code

function d8cache_do_invalidate_cache_tags($tags) {
  $tag_cache =& drupal_static('d8cache_tag_cache', array());
  $invalidated_tags =& drupal_static('d8cache_invalidated_tags', array());
  $connection = Database::getConnection();
  if ($connection
    ->inTransaction()) {
    throw new Exception('Must be outside of a transaction!');
  }

  // Ensure tags are cleared in a deterministic order by sorting them first.
  // This prevents an edge case between multiple transactions that can
  // cause a deadlock.
  $tags = array_unique($tags);
  sort($tags);
  $transaction = db_transaction();
  foreach ($tags as $tag) {

    // Only invalidate tags once per request unless they are written again.
    if (isset($invalidated_tags[$tag])) {
      continue;
    }
    $invalidated_tags[$tag] = TRUE;
    unset($tag_cache[$tag]);
    try {
      db_merge('d8cache_cache_tags')
        ->key([
        'tag' => $tag,
      ])
        ->fields([
        'invalidations' => 1,
      ])
        ->expression('invalidations', 'invalidations + 1')
        ->execute();
    } catch (Exception $e) {
      $transaction
        ->rollback();
      throw $e;
    }
  }

  // COMMIT
  unset($transaction);

  // Ensure the cache tags cache is invalidated too.
  foreach ($tags as $tag) {
    _d8cache_cache_tags_invalidate_cache($tag);
  }
}