mirror of
https://gitee.com/hyperf/hyperf.git
synced 2024-12-02 19:58:22 +08:00
Added default frequency.
This commit is contained in:
parent
e3a76bbc1b
commit
0847376e26
@ -12,82 +12,8 @@ declare(strict_types=1);
|
||||
|
||||
namespace Hyperf\DbConnection;
|
||||
|
||||
use Hyperf\Contract\FrequencyInterface;
|
||||
use Hyperf\Pool\LowFrequencyInterface;
|
||||
use Hyperf\Pool\Frequency as DefaultFrequency;
|
||||
|
||||
class Frequency implements FrequencyInterface, LowFrequencyInterface
|
||||
class Frequency extends DefaultFrequency
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $hits = [];
|
||||
|
||||
/**
|
||||
* How much time do you want to calculate the frequency ?
|
||||
* @var int
|
||||
*/
|
||||
protected $time = 10;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $lowFrequency = 5;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $beginTime;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->beginTime = time();
|
||||
}
|
||||
|
||||
public function hit(int $number = 1): bool
|
||||
{
|
||||
$this->flush();
|
||||
|
||||
$now = time();
|
||||
$hit = $this->hits[$now] ?? 0;
|
||||
$this->hits[$now] = $number + $hit;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function frequency(): float
|
||||
{
|
||||
$this->flush();
|
||||
|
||||
$hits = 0;
|
||||
$count = 0;
|
||||
foreach ($this->hits as $hit) {
|
||||
++$count;
|
||||
$hits += $hit;
|
||||
}
|
||||
|
||||
return floatval($hits / $count);
|
||||
}
|
||||
|
||||
public function isLowFrequency(): bool
|
||||
{
|
||||
return $this->frequency() < $this->lowFrequency;
|
||||
}
|
||||
|
||||
protected function flush(): void
|
||||
{
|
||||
$now = time();
|
||||
$latest = $now - $this->time;
|
||||
foreach ($this->hits as $time => $hit) {
|
||||
if ($time < $latest) {
|
||||
unset($this->hits[$time]);
|
||||
}
|
||||
}
|
||||
|
||||
if (count($this->hits) < $this->time) {
|
||||
$beginTime = $this->beginTime < $latest ? $latest : $this->beginTime;
|
||||
for ($i = $beginTime; $i < $now; ++$i) {
|
||||
$this->hits[$i] = $this->hits[$i] ?? 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
1
src/pool/.gitattributes
vendored
Normal file
1
src/pool/.gitattributes
vendored
Normal file
@ -0,0 +1 @@
|
||||
/tests export-ignore
|
92
src/pool/src/Frequency.php
Normal file
92
src/pool/src/Frequency.php
Normal file
@ -0,0 +1,92 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://doc.hyperf.io
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf-cloud/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
namespace Hyperf\Pool;
|
||||
|
||||
use Hyperf\Contract\FrequencyInterface;
|
||||
|
||||
class Frequency implements FrequencyInterface, LowFrequencyInterface
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $hits = [];
|
||||
|
||||
/**
|
||||
* How much time do you want to calculate the frequency ?
|
||||
* @var int
|
||||
*/
|
||||
protected $time = 10;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $lowFrequency = 5;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $beginTime;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->beginTime = time();
|
||||
}
|
||||
|
||||
public function hit(int $number = 1): bool
|
||||
{
|
||||
$this->flush();
|
||||
|
||||
$now = time();
|
||||
$hit = $this->hits[$now] ?? 0;
|
||||
$this->hits[$now] = $number + $hit;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function frequency(): float
|
||||
{
|
||||
$this->flush();
|
||||
|
||||
$hits = 0;
|
||||
$count = 0;
|
||||
foreach ($this->hits as $hit) {
|
||||
++$count;
|
||||
$hits += $hit;
|
||||
}
|
||||
|
||||
return floatval($hits / $count);
|
||||
}
|
||||
|
||||
public function isLowFrequency(): bool
|
||||
{
|
||||
return $this->frequency() < $this->lowFrequency;
|
||||
}
|
||||
|
||||
protected function flush(): void
|
||||
{
|
||||
$now = time();
|
||||
$latest = $now - $this->time;
|
||||
foreach ($this->hits as $time => $hit) {
|
||||
if ($time < $latest) {
|
||||
unset($this->hits[$time]);
|
||||
}
|
||||
}
|
||||
|
||||
if (count($this->hits) < $this->time) {
|
||||
$beginTime = max($this->beginTime, $latest);
|
||||
for ($i = $beginTime; $i < $now; ++$i) {
|
||||
$this->hits[$i] = $this->hits[$i] ?? 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
75
src/pool/tests/FrequencyTest.php
Normal file
75
src/pool/tests/FrequencyTest.php
Normal file
@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://doc.hyperf.io
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf-cloud/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
namespace HyperfTest\Pool;
|
||||
|
||||
use HyperfTest\Pool\Stub\FrequencyStub;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* @coversNothing
|
||||
*/
|
||||
class FrequencyTest extends TestCase
|
||||
{
|
||||
public function testFrequencyHit()
|
||||
{
|
||||
$frequency = new FrequencyStub();
|
||||
$now = time();
|
||||
$frequency->setBeginTime($now - 4);
|
||||
$frequency->setHits([
|
||||
$now => 1,
|
||||
$now - 1 => 10,
|
||||
$now - 2 => 10,
|
||||
$now - 3 => 10,
|
||||
$now - 4 => 10,
|
||||
]);
|
||||
|
||||
$num = $frequency->frequency();
|
||||
$this->assertSame(41 / 5, $num);
|
||||
|
||||
$frequency->hit();
|
||||
$num = $frequency->frequency();
|
||||
$this->assertSame(42 / 5, $num);
|
||||
}
|
||||
|
||||
public function testFrequencyHitOneSecondAfter()
|
||||
{
|
||||
$frequency = new FrequencyStub();
|
||||
$now = time();
|
||||
|
||||
$frequency->setBeginTime($now - 4);
|
||||
$frequency->setHits([
|
||||
$now => 1,
|
||||
$now - 1 => 10,
|
||||
$now - 2 => 10,
|
||||
$now - 4 => 10,
|
||||
]);
|
||||
$num = $frequency->frequency();
|
||||
$this->assertSame(31 / 5, $num);
|
||||
$frequency->hit();
|
||||
$num = $frequency->frequency();
|
||||
$this->assertSame(32 / 5, $num);
|
||||
|
||||
$frequency->setHits([
|
||||
$now => 1,
|
||||
$now - 1 => 10,
|
||||
$now - 2 => 10,
|
||||
$now - 3 => 10,
|
||||
]);
|
||||
$num = $frequency->frequency();
|
||||
$this->assertSame(31 / 5, $num);
|
||||
$frequency->hit();
|
||||
$num = $frequency->frequency();
|
||||
$this->assertSame(32 / 5, $num);
|
||||
}
|
||||
}
|
33
src/pool/tests/Stub/FrequencyStub.php
Normal file
33
src/pool/tests/Stub/FrequencyStub.php
Normal file
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://doc.hyperf.io
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf-cloud/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
namespace HyperfTest\Pool\Stub;
|
||||
|
||||
use Hyperf\Pool\Frequency;
|
||||
|
||||
class FrequencyStub extends Frequency
|
||||
{
|
||||
public function setBeginTime($time)
|
||||
{
|
||||
$this->beginTime = $time;
|
||||
}
|
||||
|
||||
public function setHits($hits)
|
||||
{
|
||||
$this->hits = $hits;
|
||||
}
|
||||
|
||||
public function getHits()
|
||||
{
|
||||
return $this->hits;
|
||||
}
|
||||
}
|
19
src/redis/src/Frequency.php
Normal file
19
src/redis/src/Frequency.php
Normal file
@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* This file is part of Hyperf.
|
||||
*
|
||||
* @link https://www.hyperf.io
|
||||
* @document https://doc.hyperf.io
|
||||
* @contact group@hyperf.io
|
||||
* @license https://github.com/hyperf-cloud/hyperf/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
namespace Hyperf\Redis;
|
||||
|
||||
use Hyperf\Pool\Frequency as DefaultFrequency;
|
||||
|
||||
class Frequency extends DefaultFrequency
|
||||
{
|
||||
}
|
@ -15,6 +15,7 @@ namespace Hyperf\Redis\Pool;
|
||||
use Hyperf\Contract\ConfigInterface;
|
||||
use Hyperf\Contract\ConnectionInterface;
|
||||
use Hyperf\Pool\Pool;
|
||||
use Hyperf\Redis\Frequency;
|
||||
use Hyperf\Redis\RedisConnection;
|
||||
use Hyperf\Utils\Arr;
|
||||
use Psr\Container\ContainerInterface;
|
||||
@ -43,6 +44,8 @@ class RedisPool extends Pool
|
||||
$this->config = $config->get($key);
|
||||
$options = Arr::get($this->config, 'pool', []);
|
||||
|
||||
$this->frequency = make(Frequency::class);
|
||||
|
||||
parent::__construct($container, $options);
|
||||
}
|
||||
|
||||
|
@ -98,6 +98,8 @@ class RedisConnection extends BaseConnection implements ConnectionInterface
|
||||
|
||||
public function close(): bool
|
||||
{
|
||||
unset($this->connection);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user