Added default frequency.

This commit is contained in:
李铭昕 2019-08-22 18:29:37 +08:00
parent e3a76bbc1b
commit 0847376e26
8 changed files with 227 additions and 76 deletions

View File

@ -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
View File

@ -0,0 +1 @@
/tests export-ignore

View 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;
}
}
}
}

View 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);
}
}

View 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;
}
}

View 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
{
}

View File

@ -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);
}

View File

@ -98,6 +98,8 @@ class RedisConnection extends BaseConnection implements ConnectionInterface
public function close(): bool
{
unset($this->connection);
return true;
}