From f7cef396d3cad14b64487eb76d3849a26f5c0111 Mon Sep 17 00:00:00 2001 From: Alexander Makarov Date: Tue, 25 Jul 2023 22:12:25 +0800 Subject: [PATCH 1/7] Fix #44: Use PSR-20 ClockInterface instead of TimerInterface --- CHANGELOG.md | 1 + README.md | 10 ++++---- composer.json | 3 ++- src/Counter.php | 22 ++++++++++-------- src/Time/MicrotimeTimer.php | 15 ------------ src/Time/SystemClock.php | 16 +++++++++++++ src/Time/TimerInterface.php | 10 -------- tests/ApcuCounterTest.php | 6 ++--- tests/BaseCounterTest.php | 15 +++++++----- tests/CounterTest.php | 6 ++--- tests/Fixtures/FrozenClock.php | 30 ++++++++++++++++++++++++ tests/Fixtures/FrozenTimeTimer.php | 37 ------------------------------ tests/MiddlewareTest.php | 7 +++--- tests/Storage/ApcuStorageTest.php | 11 +++++---- tests/Storage/StorageTest.php | 8 +++---- 15 files changed, 95 insertions(+), 102 deletions(-) delete mode 100644 src/Time/MicrotimeTimer.php create mode 100644 src/Time/SystemClock.php delete mode 100644 src/Time/TimerInterface.php create mode 100644 tests/Fixtures/FrozenClock.php delete mode 100644 tests/Fixtures/FrozenTimeTimer.php diff --git a/CHANGELOG.md b/CHANGELOG.md index c000105..6dbd896 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## 3.0.0 under development +- Chg #44: Use PSR-20 `ClockInterface` instead of `TimerInterface` (@samdark) - New #43: Add APCu counters storage (@jiaweipan) - Enh #41: Adapt package to concurrent requests, for this `StorageInterface` method `save()` split to `saveIfNotExists()` and `saveCompareAndSwap()` (@jiaweipan) diff --git a/README.md b/README.md index 8230963..a2487e0 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ [![static analysis](https://github.com/yiisoft/rate-limiter/workflows/static%20analysis/badge.svg)](https://github.com/yiisoft/rate-limiter/actions?query=workflow%3A%22static+analysis%22) [![type-coverage](https://shepherd.dev/github/yiisoft/rate-limiter/coverage.svg)](https://shepherd.dev/github/yiisoft/rate-limiter) -Rate limiter middleware helps to prevent abuse by limiting the number of requests that could be me made consequentially. +Rate limiter middleware helps to prevent abuse by limiting the number of requests that could be made consequentially. For example, you may want to limit the API usage of each user to be at most 100 API calls within a period of 10 minutes. If too many requests are received from a user within the stated period of the time, a response with status code 429 @@ -61,9 +61,9 @@ are limited and 5 is a period to apply limit to, in seconds. The `Counter` implements [generic cell rate limit algorithm (GCRA)](https://en.wikipedia.org/wiki/Generic_cell_rate_algorithm) that ensures that after reaching the limit further increments are distributed equally. -> Note: While it is sufficiently effective, it is preferred to use [Nginx](https://www.nginx.com/blog/rate-limiting-nginx/) +> Note: While it's sufficiently effective, it's preferred to use [Nginx](https://www.nginx.com/blog/rate-limiting-nginx/) > or another webserver capabilities for rate limiting. This package allows rate-limiting in the project with deployment -> environment you cannot control such as installable CMS. +> environment you can't control such as installable CMS. ### Implementing your own limiting policy @@ -84,7 +84,7 @@ Easiest way to customize a policy is to use `LimitCallback`: ```php $middleware = new LimitRequestsMiddleware($counter, $responseFactory, new LimitCallback(function (ServerRequestInterface $request): string { - // return user id from database if authentication id used i.e. limit guests and each authenticated user separately. + // return user id from a database if authentication id used i.e. limit guests and each authenticated user separately. })); ``` @@ -127,7 +127,7 @@ The code is statically analyzed with [Psalm](https://psalm.dev/). To run static ## License -The Yii Rate Limiter Middleware is free software. It is released under the terms of the BSD License. +The Yii Rate Limiter Middleware is free software. It's released under the terms of the BSD License. Please see [`LICENSE`](./LICENSE.md) for more information. Maintained by [Yii Software](https://www.yiiframework.com/). diff --git a/composer.json b/composer.json index 7343016..41a0f86 100644 --- a/composer.json +++ b/composer.json @@ -28,7 +28,8 @@ "psr/http-server-handler": "^1.0", "psr/http-server-middleware": "^1.0", "psr/simple-cache": "^2.0|^3.0", - "yiisoft/http": "^1.2" + "yiisoft/http": "^1.2", + "psr/clock": "^1.0" }, "require-dev": { "ext-apcu": "*", diff --git a/src/Counter.php b/src/Counter.php index 7658010..f9df77c 100644 --- a/src/Counter.php +++ b/src/Counter.php @@ -4,9 +4,11 @@ namespace Yiisoft\Yii\RateLimiter; +use _PHPStan_d55c4f2c2\React\Http\Io\Clock; use InvalidArgumentException; +use Psr\Clock\ClockInterface; use Yiisoft\Yii\RateLimiter\Storage\StorageInterface; -use Yiisoft\Yii\RateLimiter\Time\MicrotimeTimer; +use Yiisoft\Yii\RateLimiter\Time\SystemClock; use Yiisoft\Yii\RateLimiter\Time\TimerInterface; /** @@ -28,19 +30,19 @@ final class Counter implements CounterInterface private int $periodInMilliseconds; /** - * @var float Maximum interval before next increment. - * In GCRA it is known as emission interval. + * @var float Maximum interval before the next increment. + * In GCRA it's known as an emission interval. */ private float $incrementIntervalInMilliseconds; - private TimerInterface $timer; + private ClockInterface $timer; /** * @param StorageInterface $storage Storage to use for counter values. - * @param int $limit Maximum number of increments that could be performed before increments are limited. + * @param int $limit A maximum number of increments that could be performed before increments are limited. * @param int $periodInSeconds Period to apply limit to. * @param int $storageTtlInSeconds Storage TTL. Should be higher than `$periodInSeconds`. * @param string $storagePrefix Storage prefix. - * @param TimerInterface|null $timer Timer instance to get current time from. + * @param ClockInterface|null $timer Timer instance to get current time from. * @param int $maxCasAttempts Maximum number of times to retry saveIfNotExists/saveCompareAndSwap operations before returning an error. */ public function __construct( @@ -49,7 +51,7 @@ public function __construct( int $periodInSeconds, private int $storageTtlInSeconds = self::DEFAULT_TTL, private string $storagePrefix = self::ID_PREFIX, - TimerInterface|null $timer = null, + ClockInterface|null $timer = null, private int $maxCasAttempts = self::DEFAULT_MAX_CAS_ATTEMPTS, ) { if ($limit < 1) { @@ -61,7 +63,7 @@ public function __construct( } $this->periodInMilliseconds = $periodInSeconds * self::MILLISECONDS_PER_SECOND; - $this->timer = $timer ?: new MicrotimeTimer(); + $this->timer = $timer ?: new SystemClock(); $this->incrementIntervalInMilliseconds = $this->periodInMilliseconds / $this->limit; } @@ -75,7 +77,7 @@ public function hit(string $id): CounterState do { // Last increment time. // In GCRA it's known as arrival time. - $lastIncrementTimeInMilliseconds = $this->timer->nowInMilliseconds(); + $lastIncrementTimeInMilliseconds = $this->timer->now()->format('U.u') * 1000; $lastStoredTheoreticalNextIncrementTime = $this->getLastStoredTheoreticalNextIncrementTime($id); @@ -112,7 +114,7 @@ public function hit(string $id): CounterState /** * @return float Theoretical increment time that would be expected from equally spaced increments at exactly rate - * limit. In GCRA it is known as TAT, theoretical arrival time. + * limit. In GCRA it's known as TAT, theoretical arrival time. */ private function calculateTheoreticalNextIncrementTime( float $lastIncrementTimeInMilliseconds, diff --git a/src/Time/MicrotimeTimer.php b/src/Time/MicrotimeTimer.php deleted file mode 100644 index cbae9af..0000000 --- a/src/Time/MicrotimeTimer.php +++ /dev/null @@ -1,15 +0,0 @@ -getStorage(), 10, @@ -72,7 +74,7 @@ public function testIncrementMustBeUniformAfterLimitIsReached(): void for ($i = 0; $i < 5; $i++) { // Move timer forward for (period in milliseconds / limit) // i.e. once in period / limit remaining allowance should be increased by 1. - FrozenTimeTimer::setTimeMark($timer->nowInMilliseconds() + 100); + $timer->modify('+100 milliseconds'); $statistics = $counter->hit('key'); $this->assertEquals(1, $statistics->getRemaining()); } @@ -82,18 +84,19 @@ public function testCustomTtl(): void { $storage = $this->getStorage(); + $clock = new FrozenClock(); $counter = new Counter( $storage, 1, 1, 1, 'rate-limiter-', - new FrozenTimeTimer() + $clock ); $counter->hit('test'); - FrozenTimeTimer::setTimeMark((new MicrotimeTimer())->nowInMilliseconds() + 2); + $clock->modify('+2 milliseconds'); self::assertNull($storage->get('rate-limiter-test')); } diff --git a/tests/CounterTest.php b/tests/CounterTest.php index a30cc88..66af27b 100644 --- a/tests/CounterTest.php +++ b/tests/CounterTest.php @@ -9,7 +9,7 @@ use Yiisoft\Yii\RateLimiter\Storage\SimpleCacheStorage; use Yiisoft\Yii\RateLimiter\Storage\StorageInterface; use Yiisoft\Yii\RateLimiter\Tests\Fixtures\FakeSimpleCacheStorage; -use Yiisoft\Yii\RateLimiter\Tests\Fixtures\FrozenTimeTimer; +use Yiisoft\Yii\RateLimiter\Tests\Fixtures\FrozenClock; final class CounterTest extends BaseCounterTest { @@ -20,11 +20,11 @@ protected function getStorage(): StorageInterface /** * Testing that in concurrent scenarios, when dirty reads occur, - * the current limiter cannot be as expected By 'SimpleCacheStorage'. + * the current limiter can't be as expected By 'SimpleCacheStorage'. */ public function testConcurrentHitsWithDirtyReading(): void { - $timer = new FrozenTimeTimer(); + $timer = new FrozenClock(); $storage = new FakeSimpleCacheStorage(new ArrayCache(), 5); $limitHits = 10; $counter = new Counter( diff --git a/tests/Fixtures/FrozenClock.php b/tests/Fixtures/FrozenClock.php new file mode 100644 index 0000000..42e0578 --- /dev/null +++ b/tests/Fixtures/FrozenClock.php @@ -0,0 +1,30 @@ +now = new DateTimeImmutable(); + } + public function now(): DateTimeImmutable + { + return $this->now; + } + + public function modify(string $modifier): void + { + $this->now = $this->now->modify($modifier); + } +} diff --git a/tests/Fixtures/FrozenTimeTimer.php b/tests/Fixtures/FrozenTimeTimer.php deleted file mode 100644 index 3f31c33..0000000 --- a/tests/Fixtures/FrozenTimeTimer.php +++ /dev/null @@ -1,37 +0,0 @@ -getStorage(); - $value = (new FrozenTimeTimer())->nowInMilliseconds(); + $value = (new DateTimeImmutable())->format('U.u') * 1000; $storage->saveIfNotExists('exists_key', $value, self::DEFAULT_TTL); $result = $storage->saveIfNotExists('exists_key', $value, self::DEFAULT_TTL); @@ -47,7 +48,7 @@ public function testSaveCompareAndSwapWithNewKey(): void { $storage = $this->getStorage(); - $newValue = (new FrozenTimeTimer())->nowInMilliseconds(); + $newValue = (new DateTimeImmutable())->format('U.u') * 1000; $oldValue = (int) $storage->get('new_key'); $result = $storage->saveCompareAndSwap( @@ -60,11 +61,11 @@ public function testSaveCompareAndSwapWithNewKey(): void $this->assertFalse($result); } - public function testSaveCompareAndSwapWithExistsKeyButOldValueDiffrent(): void + public function testSaveCompareAndSwapWithExistsKeyButOldValueDifferent(): void { $storage = $this->getStorage(); - $oldValue = (new FrozenTimeTimer())->nowInMilliseconds(); + $oldValue = (new DateTimeImmutable())->format('U.u') * 1000; $storage->saveIfNotExists('exists_key', $oldValue, self::DEFAULT_TTL); $oldValue = $oldValue + 200; diff --git a/tests/Storage/StorageTest.php b/tests/Storage/StorageTest.php index 46737a5..587da85 100644 --- a/tests/Storage/StorageTest.php +++ b/tests/Storage/StorageTest.php @@ -4,9 +4,9 @@ namespace Yiisoft\Yii\RateLimiter\Tests\Storage; +use DateTimeImmutable; use PHPUnit\Framework\TestCase; use Yiisoft\Yii\RateLimiter\Storage\StorageInterface; -use Yiisoft\Yii\RateLimiter\Tests\Fixtures\FrozenTimeTimer; abstract class StorageTest extends TestCase { @@ -34,7 +34,7 @@ public function testGetKeyWithExistsKey(): void { $storage = $this->getStorage(); - $want = (new FrozenTimeTimer())->nowInMilliseconds(); + $want = (new DateTimeImmutable())->format('U.u') * 1000; $storage->saveIfNotExists('exists_key', $want, self::DEFAULT_TTL); @@ -47,7 +47,7 @@ public function testSaveIfNotExistsWithNewKey(): void { $storage = $this->getStorage(); - $value = (new FrozenTimeTimer())->nowInMilliseconds(); + $value = (new DateTimeImmutable())->format('U.u') * 1000; $result = $storage->saveIfNotExists('new_key', $value, self::DEFAULT_TTL); @@ -58,7 +58,7 @@ public function testSaveCompareAndSwapWithExistsKeyAndOldValueSame(): void { $storage = $this->getStorage(); - $oldValue = (new FrozenTimeTimer())->nowInMilliseconds(); + $oldValue = (new DateTimeImmutable())->format('U.u') * 1000; $storage->saveIfNotExists('exists_key', $oldValue, self::DEFAULT_TTL); $newValue = $oldValue + 100; From 34d48147f7d8369a5c8f2376f151aeaac5244b1f Mon Sep 17 00:00:00 2001 From: StyleCI Bot Date: Tue, 25 Jul 2023 14:13:33 +0000 Subject: [PATCH 2/7] Apply fixes from StyleCI --- src/Counter.php | 2 -- tests/BaseCounterTest.php | 2 -- tests/Fixtures/FakeApcuStorage.php | 2 +- tests/Fixtures/FrozenClock.php | 3 ++- tests/MiddlewareTest.php | 1 - tests/Storage/ApcuStorageTest.php | 1 - 6 files changed, 3 insertions(+), 8 deletions(-) diff --git a/src/Counter.php b/src/Counter.php index f9df77c..46a0e06 100644 --- a/src/Counter.php +++ b/src/Counter.php @@ -4,12 +4,10 @@ namespace Yiisoft\Yii\RateLimiter; -use _PHPStan_d55c4f2c2\React\Http\Io\Clock; use InvalidArgumentException; use Psr\Clock\ClockInterface; use Yiisoft\Yii\RateLimiter\Storage\StorageInterface; use Yiisoft\Yii\RateLimiter\Time\SystemClock; -use Yiisoft\Yii\RateLimiter\Time\TimerInterface; /** * Counter implements generic cell rate limit algorithm (GCRA) that ensures that after reaching the limit further diff --git a/tests/BaseCounterTest.php b/tests/BaseCounterTest.php index 9a995a4..32a8536 100644 --- a/tests/BaseCounterTest.php +++ b/tests/BaseCounterTest.php @@ -4,13 +4,11 @@ namespace Yiisoft\Yii\RateLimiter\Tests; -use DateTimeImmutable; use InvalidArgumentException; use PHPUnit\Framework\TestCase; use Yiisoft\Yii\RateLimiter\Counter; use Yiisoft\Yii\RateLimiter\Storage\StorageInterface; use Yiisoft\Yii\RateLimiter\Tests\Fixtures\FrozenClock; -use Yiisoft\Yii\RateLimiter\Time\SystemClock; use Yiisoft\Yii\RateLimiter\Tests\Support\Assert; abstract class BaseCounterTest extends TestCase diff --git a/tests/Fixtures/FakeApcuStorage.php b/tests/Fixtures/FakeApcuStorage.php index 73f9543..19f1d03 100644 --- a/tests/Fixtures/FakeApcuStorage.php +++ b/tests/Fixtures/FakeApcuStorage.php @@ -45,7 +45,7 @@ public function get(string $key): ?float if ($readValue === false) { return null; } - + $readValue = (float) ($readValue / $this->fixPrecisionRate); $this->dirtyReadValue = $readValue; $this->remainingDirtyReadCount = $this->dirtyReadCount; diff --git a/tests/Fixtures/FrozenClock.php b/tests/Fixtures/FrozenClock.php index 42e0578..5c319e1 100644 --- a/tests/Fixtures/FrozenClock.php +++ b/tests/Fixtures/FrozenClock.php @@ -12,12 +12,13 @@ */ final class FrozenClock implements ClockInterface { - private DateTimeImmutable $now; + public function __construct() { $this->now = new DateTimeImmutable(); } + public function now(): DateTimeImmutable { return $this->now; diff --git a/tests/MiddlewareTest.php b/tests/MiddlewareTest.php index 70250ef..6c3e213 100644 --- a/tests/MiddlewareTest.php +++ b/tests/MiddlewareTest.php @@ -4,7 +4,6 @@ namespace Yiisoft\Yii\RateLimiter\Tests; -use DateTimeImmutable; use Nyholm\Psr7\Factory\Psr17Factory; use Nyholm\Psr7\Response; use Nyholm\Psr7\ServerRequest; diff --git a/tests/Storage/ApcuStorageTest.php b/tests/Storage/ApcuStorageTest.php index 1c8ada2..18ac5f7 100644 --- a/tests/Storage/ApcuStorageTest.php +++ b/tests/Storage/ApcuStorageTest.php @@ -7,7 +7,6 @@ use DateTimeImmutable; use Yiisoft\Yii\RateLimiter\Storage\ApcuStorage; use Yiisoft\Yii\RateLimiter\Storage\StorageInterface; -use Yiisoft\Yii\RateLimiter\Tests\Fixtures\FrozenClock; final class ApcuStorageTest extends StorageTest { From 841734b5addcd8cc893c4458b06274c6cd67d94d Mon Sep 17 00:00:00 2001 From: Alexander Makarov Date: Tue, 25 Jul 2023 22:18:20 +0800 Subject: [PATCH 3/7] Fix --- src/Counter.php | 2 +- tests/Storage/ApcuStorageTest.php | 6 +++--- tests/Storage/StorageTest.php | 8 ++++---- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Counter.php b/src/Counter.php index 46a0e06..f4e6839 100644 --- a/src/Counter.php +++ b/src/Counter.php @@ -75,7 +75,7 @@ public function hit(string $id): CounterState do { // Last increment time. // In GCRA it's known as arrival time. - $lastIncrementTimeInMilliseconds = $this->timer->now()->format('U.u') * 1000; + $lastIncrementTimeInMilliseconds = round($this->timer->now()->format('U.u') * 1000); $lastStoredTheoreticalNextIncrementTime = $this->getLastStoredTheoreticalNextIncrementTime($id); diff --git a/tests/Storage/ApcuStorageTest.php b/tests/Storage/ApcuStorageTest.php index 18ac5f7..72f5adc 100644 --- a/tests/Storage/ApcuStorageTest.php +++ b/tests/Storage/ApcuStorageTest.php @@ -35,7 +35,7 @@ public function testSaveIfNotExistsWithExistsKey(): void { $storage = $this->getStorage(); - $value = (new DateTimeImmutable())->format('U.u') * 1000; + $value = round((new DateTimeImmutable())->format('U.u') * 1000); $storage->saveIfNotExists('exists_key', $value, self::DEFAULT_TTL); $result = $storage->saveIfNotExists('exists_key', $value, self::DEFAULT_TTL); @@ -47,7 +47,7 @@ public function testSaveCompareAndSwapWithNewKey(): void { $storage = $this->getStorage(); - $newValue = (new DateTimeImmutable())->format('U.u') * 1000; + $newValue = round((new DateTimeImmutable())->format('U.u') * 1000); $oldValue = (int) $storage->get('new_key'); $result = $storage->saveCompareAndSwap( @@ -64,7 +64,7 @@ public function testSaveCompareAndSwapWithExistsKeyButOldValueDifferent(): void { $storage = $this->getStorage(); - $oldValue = (new DateTimeImmutable())->format('U.u') * 1000; + $oldValue = round((new DateTimeImmutable())->format('U.u') * 1000); $storage->saveIfNotExists('exists_key', $oldValue, self::DEFAULT_TTL); $oldValue = $oldValue + 200; diff --git a/tests/Storage/StorageTest.php b/tests/Storage/StorageTest.php index 587da85..b0d3f2e 100644 --- a/tests/Storage/StorageTest.php +++ b/tests/Storage/StorageTest.php @@ -34,20 +34,20 @@ public function testGetKeyWithExistsKey(): void { $storage = $this->getStorage(); - $want = (new DateTimeImmutable())->format('U.u') * 1000; + $want = round((new DateTimeImmutable())->format('U.u') * 1000); $storage->saveIfNotExists('exists_key', $want, self::DEFAULT_TTL); $result = $storage->get('exists_key'); - $this->assertEquals($result, $want); + $this->assertEquals($want, $result); } public function testSaveIfNotExistsWithNewKey(): void { $storage = $this->getStorage(); - $value = (new DateTimeImmutable())->format('U.u') * 1000; + $value = round((new DateTimeImmutable())->format('U.u') * 1000); $result = $storage->saveIfNotExists('new_key', $value, self::DEFAULT_TTL); @@ -58,7 +58,7 @@ public function testSaveCompareAndSwapWithExistsKeyAndOldValueSame(): void { $storage = $this->getStorage(); - $oldValue = (new DateTimeImmutable())->format('U.u') * 1000; + $oldValue = round((new DateTimeImmutable())->format('U.u') * 1000); $storage->saveIfNotExists('exists_key', $oldValue, self::DEFAULT_TTL); $newValue = $oldValue + 100; From 9aaddfd3e83f349be081226f7617eba2bd41148d Mon Sep 17 00:00:00 2001 From: Alexander Makarov Date: Tue, 25 Jul 2023 22:23:24 +0800 Subject: [PATCH 4/7] Fix --- src/Counter.php | 2 +- tests/Storage/ApcuStorageTest.php | 6 +++--- tests/Storage/StorageTest.php | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Counter.php b/src/Counter.php index f4e6839..4578849 100644 --- a/src/Counter.php +++ b/src/Counter.php @@ -75,7 +75,7 @@ public function hit(string $id): CounterState do { // Last increment time. // In GCRA it's known as arrival time. - $lastIncrementTimeInMilliseconds = round($this->timer->now()->format('U.u') * 1000); + $lastIncrementTimeInMilliseconds = round((float)$this->timer->now()->format('U.u') * 1000); $lastStoredTheoreticalNextIncrementTime = $this->getLastStoredTheoreticalNextIncrementTime($id); diff --git a/tests/Storage/ApcuStorageTest.php b/tests/Storage/ApcuStorageTest.php index 72f5adc..a605ac7 100644 --- a/tests/Storage/ApcuStorageTest.php +++ b/tests/Storage/ApcuStorageTest.php @@ -35,7 +35,7 @@ public function testSaveIfNotExistsWithExistsKey(): void { $storage = $this->getStorage(); - $value = round((new DateTimeImmutable())->format('U.u') * 1000); + $value = round((float)$this->timer->now()->format('U.u') * 1000); $storage->saveIfNotExists('exists_key', $value, self::DEFAULT_TTL); $result = $storage->saveIfNotExists('exists_key', $value, self::DEFAULT_TTL); @@ -47,7 +47,7 @@ public function testSaveCompareAndSwapWithNewKey(): void { $storage = $this->getStorage(); - $newValue = round((new DateTimeImmutable())->format('U.u') * 1000); + $newValue = round((float)$this->timer->now()->format('U.u') * 1000); $oldValue = (int) $storage->get('new_key'); $result = $storage->saveCompareAndSwap( @@ -64,7 +64,7 @@ public function testSaveCompareAndSwapWithExistsKeyButOldValueDifferent(): void { $storage = $this->getStorage(); - $oldValue = round((new DateTimeImmutable())->format('U.u') * 1000); + $oldValue = round((float)$this->timer->now()->format('U.u') * 1000); $storage->saveIfNotExists('exists_key', $oldValue, self::DEFAULT_TTL); $oldValue = $oldValue + 200; diff --git a/tests/Storage/StorageTest.php b/tests/Storage/StorageTest.php index b0d3f2e..cb02c01 100644 --- a/tests/Storage/StorageTest.php +++ b/tests/Storage/StorageTest.php @@ -34,7 +34,7 @@ public function testGetKeyWithExistsKey(): void { $storage = $this->getStorage(); - $want = round((new DateTimeImmutable())->format('U.u') * 1000); + $want = round((float)$this->timer->now()->format('U.u') * 1000); $storage->saveIfNotExists('exists_key', $want, self::DEFAULT_TTL); @@ -47,7 +47,7 @@ public function testSaveIfNotExistsWithNewKey(): void { $storage = $this->getStorage(); - $value = round((new DateTimeImmutable())->format('U.u') * 1000); + $value = round((float)$this->timer->now()->format('U.u') * 1000); $result = $storage->saveIfNotExists('new_key', $value, self::DEFAULT_TTL); @@ -58,7 +58,7 @@ public function testSaveCompareAndSwapWithExistsKeyAndOldValueSame(): void { $storage = $this->getStorage(); - $oldValue = round((new DateTimeImmutable())->format('U.u') * 1000); + $oldValue = round((float)$this->timer->now()->format('U.u') * 1000); $storage->saveIfNotExists('exists_key', $oldValue, self::DEFAULT_TTL); $newValue = $oldValue + 100; From d2de4b2747738db8305aef8db6e1ca2c185cfbd4 Mon Sep 17 00:00:00 2001 From: StyleCI Bot Date: Tue, 25 Jul 2023 14:23:38 +0000 Subject: [PATCH 5/7] Apply fixes from StyleCI --- tests/Storage/ApcuStorageTest.php | 1 - tests/Storage/StorageTest.php | 1 - 2 files changed, 2 deletions(-) diff --git a/tests/Storage/ApcuStorageTest.php b/tests/Storage/ApcuStorageTest.php index a605ac7..c7de67e 100644 --- a/tests/Storage/ApcuStorageTest.php +++ b/tests/Storage/ApcuStorageTest.php @@ -4,7 +4,6 @@ namespace Yiisoft\Yii\RateLimiter\Tests\Storage; -use DateTimeImmutable; use Yiisoft\Yii\RateLimiter\Storage\ApcuStorage; use Yiisoft\Yii\RateLimiter\Storage\StorageInterface; diff --git a/tests/Storage/StorageTest.php b/tests/Storage/StorageTest.php index cb02c01..7f26f1a 100644 --- a/tests/Storage/StorageTest.php +++ b/tests/Storage/StorageTest.php @@ -4,7 +4,6 @@ namespace Yiisoft\Yii\RateLimiter\Tests\Storage; -use DateTimeImmutable; use PHPUnit\Framework\TestCase; use Yiisoft\Yii\RateLimiter\Storage\StorageInterface; From 01a643c01b24a870f20e4e6b0efb8f0bef03a3ce Mon Sep 17 00:00:00 2001 From: Alexander Makarov Date: Tue, 25 Jul 2023 22:25:48 +0800 Subject: [PATCH 6/7] Fix --- tests/Storage/ApcuStorageTest.php | 6 +++--- tests/Storage/StorageTest.php | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/Storage/ApcuStorageTest.php b/tests/Storage/ApcuStorageTest.php index c7de67e..6c9ac7e 100644 --- a/tests/Storage/ApcuStorageTest.php +++ b/tests/Storage/ApcuStorageTest.php @@ -34,7 +34,7 @@ public function testSaveIfNotExistsWithExistsKey(): void { $storage = $this->getStorage(); - $value = round((float)$this->timer->now()->format('U.u') * 1000); + $value = round((float)(new DateTimeImmutable())->format('U.u') * 1000); $storage->saveIfNotExists('exists_key', $value, self::DEFAULT_TTL); $result = $storage->saveIfNotExists('exists_key', $value, self::DEFAULT_TTL); @@ -46,7 +46,7 @@ public function testSaveCompareAndSwapWithNewKey(): void { $storage = $this->getStorage(); - $newValue = round((float)$this->timer->now()->format('U.u') * 1000); + $newValue = round((float)(new DateTimeImmutable())->format('U.u') * 1000); $oldValue = (int) $storage->get('new_key'); $result = $storage->saveCompareAndSwap( @@ -63,7 +63,7 @@ public function testSaveCompareAndSwapWithExistsKeyButOldValueDifferent(): void { $storage = $this->getStorage(); - $oldValue = round((float)$this->timer->now()->format('U.u') * 1000); + $oldValue = round((float)(new DateTimeImmutable())->format('U.u') * 1000); $storage->saveIfNotExists('exists_key', $oldValue, self::DEFAULT_TTL); $oldValue = $oldValue + 200; diff --git a/tests/Storage/StorageTest.php b/tests/Storage/StorageTest.php index 7f26f1a..3767c01 100644 --- a/tests/Storage/StorageTest.php +++ b/tests/Storage/StorageTest.php @@ -33,7 +33,7 @@ public function testGetKeyWithExistsKey(): void { $storage = $this->getStorage(); - $want = round((float)$this->timer->now()->format('U.u') * 1000); + $want = round((float)(new DateTimeImmutable())->format('U.u') * 1000); $storage->saveIfNotExists('exists_key', $want, self::DEFAULT_TTL); @@ -46,7 +46,7 @@ public function testSaveIfNotExistsWithNewKey(): void { $storage = $this->getStorage(); - $value = round((float)$this->timer->now()->format('U.u') * 1000); + $value = round((float)(new DateTimeImmutable())->format('U.u') * 1000); $result = $storage->saveIfNotExists('new_key', $value, self::DEFAULT_TTL); @@ -57,7 +57,7 @@ public function testSaveCompareAndSwapWithExistsKeyAndOldValueSame(): void { $storage = $this->getStorage(); - $oldValue = round((float)$this->timer->now()->format('U.u') * 1000); + $oldValue = round((float)(new DateTimeImmutable())->format('U.u') * 1000); $storage->saveIfNotExists('exists_key', $oldValue, self::DEFAULT_TTL); $newValue = $oldValue + 100; From 3d9c254435492913096e15481dda9559f70a0833 Mon Sep 17 00:00:00 2001 From: Alexander Makarov Date: Tue, 25 Jul 2023 22:27:51 +0800 Subject: [PATCH 7/7] Fix --- tests/Storage/ApcuStorageTest.php | 1 + tests/Storage/StorageTest.php | 1 + 2 files changed, 2 insertions(+) diff --git a/tests/Storage/ApcuStorageTest.php b/tests/Storage/ApcuStorageTest.php index 6c9ac7e..ec9baf1 100644 --- a/tests/Storage/ApcuStorageTest.php +++ b/tests/Storage/ApcuStorageTest.php @@ -4,6 +4,7 @@ namespace Yiisoft\Yii\RateLimiter\Tests\Storage; +use DateTimeImmutable; use Yiisoft\Yii\RateLimiter\Storage\ApcuStorage; use Yiisoft\Yii\RateLimiter\Storage\StorageInterface; diff --git a/tests/Storage/StorageTest.php b/tests/Storage/StorageTest.php index 3767c01..1355d32 100644 --- a/tests/Storage/StorageTest.php +++ b/tests/Storage/StorageTest.php @@ -4,6 +4,7 @@ namespace Yiisoft\Yii\RateLimiter\Tests\Storage; +use DateTimeImmutable; use PHPUnit\Framework\TestCase; use Yiisoft\Yii\RateLimiter\Storage\StorageInterface;