3 namespace Drupal\Core\Cache;
5 * Defines a chained cache implementation for combining multiple cache backends.
7 * Can be used to combine two or more backends together to behave as if they
8 * were a single backend.
10 * For example a slower, persistent storage engine could be combined with a
11 * faster, volatile storage engine. When retrieving items from cache, they will
12 * be fetched from the volatile backend first, only falling back to the
13 * persistent backend if an item is not available. An item not present in the
14 * volatile backend but found in the persistent one will be propagated back up
15 * to ensure fast retrieval on the next request. On cache sets and deletes, both
16 * backends will be invoked to ensure consistency.
18 * @see \Drupal\Core\Cache\ChainedFastBackend
22 class BackendChain implements CacheBackendInterface, CacheTagsInvalidatorInterface {
25 * Ordered list of CacheBackendInterface instances.
29 protected $backends = [];
32 * Constructs a DatabaseBackend object.
35 * The cache bin for which the object is created.
37 public function __construct($bin) {
41 * Appends a cache backend to the cache chain.
43 * @param CacheBackendInterface $backend
44 * The cache backend to be appended to the cache chain.
46 * @return \Drupal\Core\Cache\BackendChain
49 public function appendBackend(CacheBackendInterface $backend) {
50 $this->backends[] = $backend;
56 * Prepends a cache backend to the cache chain.
58 * @param CacheBackendInterface $backend
59 * The backend to be prepended to the cache chain.
61 * @return \Drupal\Core\Cache\BackendChain
64 public function prependBackend(CacheBackendInterface $backend) {
65 array_unshift($this->backends, $backend);
73 public function get($cid, $allow_invalid = FALSE) {
74 foreach ($this->backends as $index => $backend) {
75 if (($return = $backend->get($cid, $allow_invalid)) !== FALSE) {
76 // We found a result, propagate it to all missed backends.
78 for ($i = ($index - 1); 0 <= $i; --$i) {
79 $this->backends[$i]->set($cid, $return->data, $return->expire, $return->tags);
93 public function getMultiple(&$cids, $allow_invalid = FALSE) {
96 foreach ($this->backends as $index => $backend) {
97 $items = $backend->getMultiple($cids, $allow_invalid);
99 // Propagate the values that could be retrieved from the current cache
100 // backend to all missed backends.
101 if ($index > 0 && !empty($items)) {
102 for ($i = ($index - 1); 0 <= $i; --$i) {
103 foreach ($items as $cached) {
104 $this->backends[$i]->set($cached->cid, $cached->data, $cached->expire, $cached->tags);
109 // Append the values to the previously retrieved ones.
113 // No need to go further if we don't have any cid to fetch left.
124 public function set($cid, $data, $expire = Cache::PERMANENT, array $tags = []) {
125 foreach ($this->backends as $backend) {
126 $backend->set($cid, $data, $expire, $tags);
133 public function setMultiple(array $items) {
134 foreach ($this->backends as $backend) {
135 $backend->setMultiple($items);
142 public function delete($cid) {
143 foreach ($this->backends as $backend) {
144 $backend->delete($cid);
151 public function deleteMultiple(array $cids) {
152 foreach ($this->backends as $backend) {
153 $backend->deleteMultiple($cids);
160 public function deleteAll() {
161 foreach ($this->backends as $backend) {
162 $backend->deleteAll();
169 public function invalidate($cid) {
170 foreach ($this->backends as $backend) {
171 $backend->invalidate($cid);
178 public function invalidateMultiple(array $cids) {
179 foreach ($this->backends as $backend) {
180 $backend->invalidateMultiple($cids);
187 public function invalidateTags(array $tags) {
188 foreach ($this->backends as $backend) {
189 if ($backend instanceof CacheTagsInvalidatorInterface) {
190 $backend->invalidateTags($tags);
198 public function invalidateAll() {
199 foreach ($this->backends as $backend) {
200 $backend->invalidateAll();
207 public function garbageCollection() {
208 foreach ($this->backends as $backend) {
209 $backend->garbageCollection();
216 public function removeBin() {
217 foreach ($this->backends as $backend) {
218 $backend->removeBin();