forked from neos/flow-development-collection
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathIterableMultiBackend.php
More file actions
142 lines (133 loc) · 5.5 KB
/
Copy pathIterableMultiBackend.php
File metadata and controls
142 lines (133 loc) · 5.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
<?php
declare(strict_types=1);
namespace Neos\Cache\Backend;
/*
* This file is part of the Neos.Cache package.
*
* (c) Contributors of the Neos Project - www.neos.io
*
* This package is Open Source Software. For the full copyright and license
* information, please view the LICENSE file which was distributed with this
* source code.
*/
use Neos\Cache\Exception;
use Neos\Flow\Log\Utility\LogEnvironment;
use Throwable;
/**
* An iterable, taggable multi backend, falling back to multiple backends if errors occur.
*/
class IterableMultiBackend extends TaggableMultiBackend implements IterableBackendInterface
{
/**
* @throws Throwable
*/
protected function buildSubBackend(string $backendClassName, array $backendOptions): ?BackendInterface
{
if (!is_subclass_of($backendClassName, IterableBackendInterface::class)) {
$message = sprintf('Failed building sub backend %s for %s because it does not implement %s', $backendClassName, get_class($this), IterableBackendInterface::class);
$throwable = new Exception($message);
$this->logger?->error(($this->throwableStorage ? $this->throwableStorage->logThrowable($throwable) : $message), LogEnvironment::fromMethodName(__METHOD__));
$this->handleError($throwable);
return null;
}
return parent::buildSubBackend($backendClassName, $backendOptions);
}
/**
* @throws Throwable
*/
public function current(): mixed
{
$this->prepareBackends();
foreach ($this->backends as $backend) {
try {
if (!method_exists($backend, 'current')) {
throw new \RuntimeException(get_class($backend) . ' does not implement rewind');
}
return $backend->current();
} catch (Throwable $throwable) {
$this->logger?->error('Failed retrieving current cache entry using backend ' . get_class($backend) . ' in ' . get_class($this) . ': ' . $this->throwableStorage?->logThrowable($throwable), LogEnvironment::fromMethodName(__METHOD__));
$this->handleError($throwable);
$this->removeUnhealthyBackend($backend);
}
}
return false;
}
/**
* @throws Throwable
*/
public function next(): void
{
$this->prepareBackends();
foreach ($this->backends as $backend) {
try {
if (!method_exists($backend, 'next')) {
throw new \RuntimeException(get_class($backend) . ' does not implement rewind');
}
$backend->next();
} catch (Throwable $throwable) {
$this->logger?->error('Failed retrieving next cache entry using backend ' . get_class($backend) . ' in ' . get_class($this) . ': ' . $this->throwableStorage?->logThrowable($throwable), LogEnvironment::fromMethodName(__METHOD__));
$this->handleError($throwable);
$this->removeUnhealthyBackend($backend);
}
}
}
/**
* @throws Throwable
*/
public function key(): string|int|bool|null|float
{
$this->prepareBackends();
foreach ($this->backends as $backend) {
try {
if (!method_exists($backend, 'key')) {
throw new \RuntimeException(get_class($backend) . ' does not implement rewind');
}
return $backend->key();
} catch (Throwable $throwable) {
$this->logger?->error('Failed retrieving cache entry key using backend ' . get_class($backend) . ' in ' . get_class($this) . ': ' . $this->throwableStorage?->logThrowable($throwable), LogEnvironment::fromMethodName(__METHOD__));
$this->handleError($throwable);
$this->removeUnhealthyBackend($backend);
}
}
return false;
}
/**
* @throws Throwable
*/
public function valid(): bool
{
$this->prepareBackends();
foreach ($this->backends as $backend) {
try {
if (!method_exists($backend, 'valid')) {
throw new \RuntimeException(get_class($backend) . ' does not implement rewind');
}
return $backend->valid();
} catch (Throwable $throwable) {
$this->logger?->error('Failed checking if current cache entry is valid using backend ' . get_class($backend) . ' in ' . get_class($this) . ': ' . $this->throwableStorage?->logThrowable($throwable), LogEnvironment::fromMethodName(__METHOD__));
$this->handleError($throwable);
$this->removeUnhealthyBackend($backend);
}
}
return false;
}
/**
* @throws Throwable
*/
public function rewind(): void
{
$this->prepareBackends();
foreach ($this->backends as $backend) {
try {
if (!method_exists($backend, 'rewind')) {
throw new \RuntimeException(get_class($backend) . ' does not implement rewind');
}
$backend->rewind();
} catch (Throwable $throwable) {
$this->logger?->error('Failed rewinding cache entries using backend ' . get_class($backend) . ' in ' . get_class($this) . ': ' . $this->throwableStorage?->logThrowable($throwable), LogEnvironment::fromMethodName(__METHOD__));
$this->handleError($throwable);
$this->removeUnhealthyBackend($backend);
}
}
}
}