Fixed unexpected behavior in retry budget for hyperf/retry. (#2693)

* fix: retry budget bug

* fix: fix travis

* Update CHANGELOG-2.0.md

Co-authored-by: 李铭昕 <715557344@qq.com>
This commit is contained in:
谷溪 2020-10-21 15:09:25 +08:00 committed by GitHub
parent 9da3463905
commit 61624519fb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 29 additions and 3 deletions

View File

@ -8,6 +8,7 @@
- [#2680](https://github.com/hyperf/hyperf/pull/2680) Fixed Type error for `CastsValue`, because `$isSynchronized` don't have default value.
- [#2680](https://github.com/hyperf/hyperf/pull/2680) Fixed default value in `$items` will be replaced by `__construct` for `CastsValue`.
- [#2693](https://github.com/hyperf/hyperf/pull/2693) Fixed unexpected behavior in retry budget for `hyperf/retry`.
- [#2695](https://github.com/hyperf/hyperf/pull/2695) Fixed method `Container::define()` does not works when the class has been resolved.
## Optimized

View File

@ -42,11 +42,17 @@ class RetryBudget implements RetryBudgetInterface
*/
private $timerId;
/**
* @var float|int
*/
private $maxToken;
public function __construct(int $ttl, int $minRetriesPerSec, float $percentCanRetry)
{
$this->ttl = $ttl;
$this->minRetriesPerSec = $minRetriesPerSec;
$this->percentCanRetry = $percentCanRetry;
$this->maxToken = ($this->minRetriesPerSec / $this->percentCanRetry) * $this->ttl;
$this->budget = new SplQueue();
}
@ -70,9 +76,7 @@ class RetryBudget implements RetryBudgetInterface
for ($i = 0; $i < $this->minRetriesPerSec / $this->percentCanRetry; ++$i) {
$this->produce();
}
while (! $this->budget->isEmpty()
&& $this->budget->top() <= microtime(true)
) {
while ($this->hasOverflown()) {
$this->budget->dequeue();
}
});
@ -98,4 +102,10 @@ class RetryBudget implements RetryBudgetInterface
$t = microtime(true) + $this->ttl;
$this->budget->push($t);
}
public function hasOverflown(): bool
{
return (! $this->budget->isEmpty() && $this->budget->bottom() <= microtime(true))
|| $this->budget->count() > $this->maxToken;
}
}

View File

@ -68,5 +68,20 @@ class RetryBudgetTest extends TestCase
$this->assertTrue($budget->consume());
$this->assertTrue($budget->consume());
$this->assertTrue(! $budget->consume());
// Retry budget should never have more than 1 token in this test
$budget = new RetryBudget(
1,
1,
1
);
$budget->init();
$ref = new \ReflectionClass(RetryBudget::class);
$prop = $ref->getProperty('budget');
$prop->setAccessible(true);
System::sleep(1.2);
$this->assertLessThanOrEqual(1, $prop->getValue($budget)->count());
System::sleep(1.2);
$this->assertLessThanOrEqual(1, $prop->getValue($budget)->count());
}
}