AnnotationManager.php 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * This file is part of Hyperf.
  5. *
  6. * @link https://www.hyperf.io
  7. * @document https://hyperf.wiki
  8. * @contact group@hyperf.io
  9. * @license https://github.com/hyperf/hyperf/blob/master/LICENSE
  10. */
  11. namespace Hyperf\Cache;
  12. use Hyperf\Cache\Annotation\Cacheable;
  13. use Hyperf\Cache\Annotation\CacheAhead;
  14. use Hyperf\Cache\Annotation\CacheEvict;
  15. use Hyperf\Cache\Annotation\CachePut;
  16. use Hyperf\Cache\Annotation\FailCache;
  17. use Hyperf\Cache\Exception\CacheException;
  18. use Hyperf\Cache\Helper\StringHelper;
  19. use Hyperf\Contract\ConfigInterface;
  20. use Hyperf\Contract\StdoutLoggerInterface;
  21. use Hyperf\Di\Annotation\AbstractAnnotation;
  22. use Hyperf\Di\Annotation\AnnotationCollector;
  23. class AnnotationManager
  24. {
  25. public function __construct(protected ConfigInterface $config, protected StdoutLoggerInterface $logger)
  26. {
  27. }
  28. public function getCacheableValue(string $className, string $method, array $arguments): array
  29. {
  30. /** @var Cacheable $annotation */
  31. $annotation = $this->getAnnotation(Cacheable::class, $className, $method);
  32. $key = $this->getFormattedKey($annotation->prefix, $arguments, $annotation->value);
  33. $group = $annotation->group;
  34. $ttl = $annotation->ttl ?? $this->config->get("cache.{$group}.ttl", 3600);
  35. $annotation->skipCacheResults ??= (array) $this->config->get("cache.{$group}.skip_cache_results", []);
  36. return [$key, $ttl + $this->getRandomOffset($annotation->offset), $group, $annotation];
  37. }
  38. public function getCacheAheadValue(string $className, string $method, array $arguments): array
  39. {
  40. /** @var CacheAhead $annotation */
  41. $annotation = $this->getAnnotation(CacheAhead::class, $className, $method);
  42. $key = $this->getFormattedKey($annotation->prefix, $arguments, $annotation->value);
  43. $group = $annotation->group;
  44. $ttl = $annotation->ttl ?? $this->config->get("cache.{$group}.ttl", 3600);
  45. $annotation->skipCacheResults ??= (array) $this->config->get("cache.{$group}.skip_cache_results", []);
  46. return [$key, $ttl + $this->getRandomOffset($annotation->offset), $group, $annotation];
  47. }
  48. public function getCacheEvictValue(string $className, string $method, array $arguments): array
  49. {
  50. /** @var CacheEvict $annotation */
  51. $annotation = $this->getAnnotation(CacheEvict::class, $className, $method);
  52. $prefix = $annotation->prefix;
  53. $all = $annotation->all;
  54. $group = $annotation->group;
  55. if (! $all) {
  56. $key = $this->getFormattedKey($prefix, $arguments, $annotation->value);
  57. } else {
  58. $key = $prefix . ':';
  59. }
  60. return [$key, $all, $group, $annotation];
  61. }
  62. public function getCachePutValue(string $className, string $method, array $arguments): array
  63. {
  64. /** @var CachePut $annotation */
  65. $annotation = $this->getAnnotation(CachePut::class, $className, $method);
  66. $key = $this->getFormattedKey($annotation->prefix, $arguments, $annotation->value);
  67. $group = $annotation->group;
  68. $ttl = $annotation->ttl ?? $this->config->get("cache.{$group}.ttl", 3600);
  69. $annotation->skipCacheResults ??= (array) $this->config->get("cache.{$group}.skip_cache_results", []);
  70. return [$key, $ttl + $this->getRandomOffset($annotation->offset), $group, $annotation];
  71. }
  72. public function getFailCacheValue(string $className, string $method, array $arguments): array
  73. {
  74. /** @var FailCache $annotation */
  75. $annotation = $this->getAnnotation(FailCache::class, $className, $method);
  76. $prefix = $annotation->prefix ?? ($className . '::' . $method);
  77. $key = $this->getFormattedKey($prefix, $arguments, $annotation->value);
  78. $group = $annotation->group;
  79. $ttl = $annotation->ttl ?? $this->config->get("cache.{$group}.ttl", 3600);
  80. $annotation->skipCacheResults ??= (array) $this->config->get("cache.{$group}.skip_cache_results", []);
  81. return [$key, $ttl, $group, $annotation];
  82. }
  83. protected function getRandomOffset(int $offset): int
  84. {
  85. if ($offset > 0) {
  86. return rand(0, $offset);
  87. }
  88. return 0;
  89. }
  90. protected function getAnnotation(string $annotation, string $className, string $method): AbstractAnnotation
  91. {
  92. $collector = AnnotationCollector::get($className);
  93. $result = $collector['_m'][$method][$annotation] ?? null;
  94. if (! $result instanceof $annotation) {
  95. throw new CacheException(sprintf('Annotation %s in %s:%s not exist.', $annotation, $className, $method));
  96. }
  97. return $result;
  98. }
  99. protected function getFormattedKey(string $prefix, array $arguments, ?string $value = null): string
  100. {
  101. return StringHelper::format($prefix, $arguments, $value);
  102. }
  103. }