EarlyExpirationHandler.php 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\Cache\Messenger;
  11. use Symfony\Component\Cache\CacheItem;
  12. use Symfony\Component\DependencyInjection\ReverseContainer;
  13. use Symfony\Component\Messenger\Handler\MessageHandlerInterface;
  14. /**
  15. * Computes cached values sent to a message bus.
  16. */
  17. class EarlyExpirationHandler implements MessageHandlerInterface
  18. {
  19. private $reverseContainer;
  20. private $processedNonces = [];
  21. public function __construct(ReverseContainer $reverseContainer)
  22. {
  23. $this->reverseContainer = $reverseContainer;
  24. }
  25. public function __invoke(EarlyExpirationMessage $message)
  26. {
  27. $item = $message->getItem();
  28. $metadata = $item->getMetadata();
  29. $expiry = $metadata[CacheItem::METADATA_EXPIRY] ?? 0;
  30. $ctime = $metadata[CacheItem::METADATA_CTIME] ?? 0;
  31. if ($expiry && $ctime) {
  32. // skip duplicate or expired messages
  33. $processingNonce = [$expiry, $ctime];
  34. $pool = $message->getPool();
  35. $key = $item->getKey();
  36. if (($this->processedNonces[$pool][$key] ?? null) === $processingNonce) {
  37. return;
  38. }
  39. if (microtime(true) >= $expiry) {
  40. return;
  41. }
  42. $this->processedNonces[$pool] = [$key => $processingNonce] + ($this->processedNonces[$pool] ?? []);
  43. if (\count($this->processedNonces[$pool]) > 100) {
  44. array_pop($this->processedNonces[$pool]);
  45. }
  46. }
  47. static $setMetadata;
  48. $setMetadata ?? $setMetadata = \Closure::bind(
  49. function (CacheItem $item, float $startTime) {
  50. if ($item->expiry > $endTime = microtime(true)) {
  51. $item->newMetadata[CacheItem::METADATA_EXPIRY] = $item->expiry;
  52. $item->newMetadata[CacheItem::METADATA_CTIME] = (int) ceil(1000 * ($endTime - $startTime));
  53. }
  54. },
  55. null,
  56. CacheItem::class
  57. );
  58. $startTime = microtime(true);
  59. $pool = $message->findPool($this->reverseContainer);
  60. $callback = $message->findCallback($this->reverseContainer);
  61. $value = $callback($item);
  62. $setMetadata($item, $startTime);
  63. $pool->save($item->set($value));
  64. }
  65. }