summaryrefslogtreecommitdiff
path: root/vendor/symfony/cache/Adapter/TraceableAdapter.php
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/symfony/cache/Adapter/TraceableAdapter.php')
-rw-r--r--vendor/symfony/cache/Adapter/TraceableAdapter.php250
1 files changed, 250 insertions, 0 deletions
diff --git a/vendor/symfony/cache/Adapter/TraceableAdapter.php b/vendor/symfony/cache/Adapter/TraceableAdapter.php
new file mode 100644
index 0000000..b5bce14
--- /dev/null
+++ b/vendor/symfony/cache/Adapter/TraceableAdapter.php
@@ -0,0 +1,250 @@
1<?php
2
3/*
4 * This file is part of the Symfony package.
5 *
6 * (c) Fabien Potencier <fabien@symfony.com>
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11
12namespace Symfony\Component\Cache\Adapter;
13
14use Psr\Cache\CacheItemInterface;
15use Symfony\Component\Cache\CacheItem;
16use Symfony\Component\Cache\PruneableInterface;
17use Symfony\Component\Cache\ResettableInterface;
18use Symfony\Contracts\Cache\CacheInterface;
19use Symfony\Contracts\Service\ResetInterface;
20
21/**
22 * An adapter that collects data about all cache calls.
23 *
24 * @author Aaron Scherer <aequasi@gmail.com>
25 * @author Tobias Nyholm <tobias.nyholm@gmail.com>
26 * @author Nicolas Grekas <p@tchwork.com>
27 */
28class TraceableAdapter implements AdapterInterface, CacheInterface, PruneableInterface, ResettableInterface
29{
30 protected AdapterInterface $pool;
31 private array $calls = [];
32
33 public function __construct(AdapterInterface $pool)
34 {
35 $this->pool = $pool;
36 }
37
38 public function get(string $key, callable $callback, ?float $beta = null, ?array &$metadata = null): mixed
39 {
40 if (!$this->pool instanceof CacheInterface) {
41 throw new \BadMethodCallException(sprintf('Cannot call "%s::get()": this class doesn\'t implement "%s".', get_debug_type($this->pool), CacheInterface::class));
42 }
43
44 $isHit = true;
45 $callback = function (CacheItem $item, bool &$save) use ($callback, &$isHit) {
46 $isHit = $item->isHit();
47
48 return $callback($item, $save);
49 };
50
51 $event = $this->start(__FUNCTION__);
52 try {
53 $value = $this->pool->get($key, $callback, $beta, $metadata);
54 $event->result[$key] = get_debug_type($value);
55 } finally {
56 $event->end = microtime(true);
57 }
58 if ($isHit) {
59 ++$event->hits;
60 } else {
61 ++$event->misses;
62 }
63
64 return $value;
65 }
66
67 public function getItem(mixed $key): CacheItem
68 {
69 $event = $this->start(__FUNCTION__);
70 try {
71 $item = $this->pool->getItem($key);
72 } finally {
73 $event->end = microtime(true);
74 }
75 if ($event->result[$key] = $item->isHit()) {
76 ++$event->hits;
77 } else {
78 ++$event->misses;
79 }
80
81 return $item;
82 }
83
84 public function hasItem(mixed $key): bool
85 {
86 $event = $this->start(__FUNCTION__);
87 try {
88 return $event->result[$key] = $this->pool->hasItem($key);
89 } finally {
90 $event->end = microtime(true);
91 }
92 }
93
94 public function deleteItem(mixed $key): bool
95 {
96 $event = $this->start(__FUNCTION__);
97 try {
98 return $event->result[$key] = $this->pool->deleteItem($key);
99 } finally {
100 $event->end = microtime(true);
101 }
102 }
103
104 public function save(CacheItemInterface $item): bool
105 {
106 $event = $this->start(__FUNCTION__);
107 try {
108 return $event->result[$item->getKey()] = $this->pool->save($item);
109 } finally {
110 $event->end = microtime(true);
111 }
112 }
113
114 public function saveDeferred(CacheItemInterface $item): bool
115 {
116 $event = $this->start(__FUNCTION__);
117 try {
118 return $event->result[$item->getKey()] = $this->pool->saveDeferred($item);
119 } finally {
120 $event->end = microtime(true);
121 }
122 }
123
124 public function getItems(array $keys = []): iterable
125 {
126 $event = $this->start(__FUNCTION__);
127 try {
128 $result = $this->pool->getItems($keys);
129 } finally {
130 $event->end = microtime(true);
131 }
132 $f = function () use ($result, $event) {
133 $event->result = [];
134 foreach ($result as $key => $item) {
135 if ($event->result[$key] = $item->isHit()) {
136 ++$event->hits;
137 } else {
138 ++$event->misses;
139 }
140 yield $key => $item;
141 }
142 };
143
144 return $f();
145 }
146
147 public function clear(string $prefix = ''): bool
148 {
149 $event = $this->start(__FUNCTION__);
150 try {
151 if ($this->pool instanceof AdapterInterface) {
152 return $event->result = $this->pool->clear($prefix);
153 }
154
155 return $event->result = $this->pool->clear();
156 } finally {
157 $event->end = microtime(true);
158 }
159 }
160
161 public function deleteItems(array $keys): bool
162 {
163 $event = $this->start(__FUNCTION__);
164 $event->result['keys'] = $keys;
165 try {
166 return $event->result['result'] = $this->pool->deleteItems($keys);
167 } finally {
168 $event->end = microtime(true);
169 }
170 }
171
172 public function commit(): bool
173 {
174 $event = $this->start(__FUNCTION__);
175 try {
176 return $event->result = $this->pool->commit();
177 } finally {
178 $event->end = microtime(true);
179 }
180 }
181
182 public function prune(): bool
183 {
184 if (!$this->pool instanceof PruneableInterface) {
185 return false;
186 }
187 $event = $this->start(__FUNCTION__);
188 try {
189 return $event->result = $this->pool->prune();
190 } finally {
191 $event->end = microtime(true);
192 }
193 }
194
195 public function reset(): void
196 {
197 if ($this->pool instanceof ResetInterface) {
198 $this->pool->reset();
199 }
200
201 $this->clearCalls();
202 }
203
204 public function delete(string $key): bool
205 {
206 $event = $this->start(__FUNCTION__);
207 try {
208 return $event->result[$key] = $this->pool->deleteItem($key);
209 } finally {
210 $event->end = microtime(true);
211 }
212 }
213
214 public function getCalls(): array
215 {
216 return $this->calls;
217 }
218
219 public function clearCalls(): void
220 {
221 $this->calls = [];
222 }
223
224 public function getPool(): AdapterInterface
225 {
226 return $this->pool;
227 }
228
229 protected function start(string $name): TraceableAdapterEvent
230 {
231 $this->calls[] = $event = new TraceableAdapterEvent();
232 $event->name = $name;
233 $event->start = microtime(true);
234
235 return $event;
236 }
237}
238
239/**
240 * @internal
241 */
242class TraceableAdapterEvent
243{
244 public string $name;
245 public float $start;
246 public float $end;
247 public array|bool $result;
248 public int $hits = 0;
249 public int $misses = 0;
250}