diff options
Diffstat (limited to 'vendor/symfony/cache/Traits/ContractsTrait.php')
-rw-r--r-- | vendor/symfony/cache/Traits/ContractsTrait.php | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/vendor/symfony/cache/Traits/ContractsTrait.php b/vendor/symfony/cache/Traits/ContractsTrait.php new file mode 100644 index 0000000..8d830f0 --- /dev/null +++ b/vendor/symfony/cache/Traits/ContractsTrait.php | |||
@@ -0,0 +1,113 @@ | |||
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 | |||
12 | namespace Symfony\Component\Cache\Traits; | ||
13 | |||
14 | use Psr\Log\LoggerInterface; | ||
15 | use Symfony\Component\Cache\Adapter\AdapterInterface; | ||
16 | use Symfony\Component\Cache\CacheItem; | ||
17 | use Symfony\Component\Cache\Exception\InvalidArgumentException; | ||
18 | use Symfony\Component\Cache\LockRegistry; | ||
19 | use Symfony\Contracts\Cache\CacheInterface; | ||
20 | use Symfony\Contracts\Cache\CacheTrait; | ||
21 | use Symfony\Contracts\Cache\ItemInterface; | ||
22 | |||
23 | /** | ||
24 | * @author Nicolas Grekas <p@tchwork.com> | ||
25 | * | ||
26 | * @internal | ||
27 | */ | ||
28 | trait ContractsTrait | ||
29 | { | ||
30 | use CacheTrait { | ||
31 | doGet as private contractsGet; | ||
32 | } | ||
33 | |||
34 | private \Closure $callbackWrapper; | ||
35 | private array $computing = []; | ||
36 | |||
37 | /** | ||
38 | * Wraps the callback passed to ->get() in a callable. | ||
39 | * | ||
40 | * @return callable the previous callback wrapper | ||
41 | */ | ||
42 | public function setCallbackWrapper(?callable $callbackWrapper): callable | ||
43 | { | ||
44 | if (!isset($this->callbackWrapper)) { | ||
45 | $this->callbackWrapper = LockRegistry::compute(...); | ||
46 | |||
47 | if (\in_array(\PHP_SAPI, ['cli', 'phpdbg', 'embed'], true)) { | ||
48 | $this->setCallbackWrapper(null); | ||
49 | } | ||
50 | } | ||
51 | |||
52 | if (null !== $callbackWrapper && !$callbackWrapper instanceof \Closure) { | ||
53 | $callbackWrapper = $callbackWrapper(...); | ||
54 | } | ||
55 | |||
56 | $previousWrapper = $this->callbackWrapper; | ||
57 | $this->callbackWrapper = $callbackWrapper ?? static fn (callable $callback, ItemInterface $item, bool &$save, CacheInterface $pool, \Closure $setMetadata, ?LoggerInterface $logger) => $callback($item, $save); | ||
58 | |||
59 | return $previousWrapper; | ||
60 | } | ||
61 | |||
62 | private function doGet(AdapterInterface $pool, string $key, callable $callback, ?float $beta, ?array &$metadata = null): mixed | ||
63 | { | ||
64 | if (0 > $beta ??= 1.0) { | ||
65 | throw new InvalidArgumentException(sprintf('Argument "$beta" provided to "%s::get()" must be a positive number, %f given.', static::class, $beta)); | ||
66 | } | ||
67 | |||
68 | static $setMetadata; | ||
69 | |||
70 | $setMetadata ??= \Closure::bind( | ||
71 | static function (CacheItem $item, float $startTime, ?array &$metadata) { | ||
72 | if ($item->expiry > $endTime = microtime(true)) { | ||
73 | $item->newMetadata[CacheItem::METADATA_EXPIRY] = $metadata[CacheItem::METADATA_EXPIRY] = $item->expiry; | ||
74 | $item->newMetadata[CacheItem::METADATA_CTIME] = $metadata[CacheItem::METADATA_CTIME] = (int) ceil(1000 * ($endTime - $startTime)); | ||
75 | } else { | ||
76 | unset($metadata[CacheItem::METADATA_EXPIRY], $metadata[CacheItem::METADATA_CTIME], $metadata[CacheItem::METADATA_TAGS]); | ||
77 | } | ||
78 | }, | ||
79 | null, | ||
80 | CacheItem::class | ||
81 | ); | ||
82 | |||
83 | $this->callbackWrapper ??= LockRegistry::compute(...); | ||
84 | |||
85 | return $this->contractsGet($pool, $key, function (CacheItem $item, bool &$save) use ($pool, $callback, $setMetadata, &$metadata, $key) { | ||
86 | // don't wrap nor save recursive calls | ||
87 | if (isset($this->computing[$key])) { | ||
88 | $value = $callback($item, $save); | ||
89 | $save = false; | ||
90 | |||
91 | return $value; | ||
92 | } | ||
93 | |||
94 | $this->computing[$key] = $key; | ||
95 | $startTime = microtime(true); | ||
96 | |||
97 | if (!isset($this->callbackWrapper)) { | ||
98 | $this->setCallbackWrapper($this->setCallbackWrapper(null)); | ||
99 | } | ||
100 | |||
101 | try { | ||
102 | $value = ($this->callbackWrapper)($callback, $item, $save, $pool, function (CacheItem $item) use ($setMetadata, $startTime, &$metadata) { | ||
103 | $setMetadata($item, $startTime, $metadata); | ||
104 | }, $this->logger ?? null); | ||
105 | $setMetadata($item, $startTime, $metadata); | ||
106 | |||
107 | return $value; | ||
108 | } finally { | ||
109 | unset($this->computing[$key]); | ||
110 | } | ||
111 | }, $beta, $metadata, $this->logger ?? null); | ||
112 | } | ||
113 | } | ||