Frequency.php 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  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\Pool;
  12. use Hyperf\Contract\FrequencyInterface;
  13. class Frequency implements FrequencyInterface, LowFrequencyInterface
  14. {
  15. /**
  16. * @var array
  17. */
  18. protected $hits = [];
  19. /**
  20. * How much time do you want to calculate the frequency ?
  21. * @var int
  22. */
  23. protected $time = 10;
  24. /**
  25. * @var int
  26. */
  27. protected $lowFrequency = 5;
  28. /**
  29. * @var int
  30. */
  31. protected $beginTime;
  32. /**
  33. * @var int
  34. */
  35. protected $lowFrequencyTime;
  36. /**
  37. * @var int
  38. */
  39. protected $lowFrequencyInterval = 60;
  40. /**
  41. * @var null|Pool
  42. */
  43. protected $pool;
  44. public function __construct(?Pool $pool = null)
  45. {
  46. $this->pool = $pool;
  47. $this->beginTime = time();
  48. $this->lowFrequencyTime = time();
  49. }
  50. public function hit(int $number = 1): bool
  51. {
  52. $this->flush();
  53. $now = time();
  54. $hit = $this->hits[$now] ?? 0;
  55. $this->hits[$now] = $number + $hit;
  56. return true;
  57. }
  58. public function frequency(): float
  59. {
  60. $this->flush();
  61. $hits = 0;
  62. $count = 0;
  63. foreach ($this->hits as $hit) {
  64. ++$count;
  65. $hits += $hit;
  66. }
  67. return floatval($hits / $count);
  68. }
  69. public function isLowFrequency(): bool
  70. {
  71. $now = time();
  72. if ($this->lowFrequencyTime + $this->lowFrequencyInterval < $now && $this->frequency() < $this->lowFrequency) {
  73. $this->lowFrequencyTime = $now;
  74. return true;
  75. }
  76. return false;
  77. }
  78. protected function flush(): void
  79. {
  80. $now = time();
  81. $latest = $now - $this->time;
  82. foreach ($this->hits as $time => $hit) {
  83. if ($time < $latest) {
  84. unset($this->hits[$time]);
  85. }
  86. }
  87. if (count($this->hits) < $this->time) {
  88. $beginTime = max($this->beginTime, $latest);
  89. for ($i = $beginTime; $i < $now; ++$i) {
  90. $this->hits[$i] = $this->hits[$i] ?? 0;
  91. }
  92. }
  93. }
  94. }