Description
Description
RateLimiter
uses usually full seconds:
time()
,sleep()
,\DateTimeImmutable::createFromFormat('U', [time])
.
Sometimes however, it goes with microseconds:
microtime(true)
,usleep()
and could use them even more widely:
\DateTimeImmutable::createFromFormat('U.u', [microtime])
,return (float) $interval->format('%f') / 1e6 // microseconds...
,public function getExpirationTime(): ?float;
.
Using float
gives an option to set interval in milliseconds:
var_dump(\DateInterval::createFromDateString('200ms')->format('%f'));
// string(6) "200000"
and also to shorten wait time (e.g. 1.8s instead of 2.0s).
Example
SlidingWindow
uses time()
which means that after running ->wait()
it is still considered as not expired.
<?php
use Symfony\Component\RateLimiter\Policy\SlidingWindow;
require_once './vendor/autoload.php';
$window = new SlidingWindow('some_id', 2);
sleep(2); // mimic $limit->wait();
var_dump($window->isExpired()); // false - same second
$window = new class ('some_id', 2) {
public function __construct(string $id, int $intervalInSeconds)
{
$this->windowEndAt = microtime(true) + $intervalInSeconds;
}
public function isExpired(): bool
{
return microtime(true) > $this->windowEndAt;
}
};
sleep(2); // mimic $limit->wait();
var_dump($window->isExpired()); // true
Summary
Before I go with a PR I would like to know if this change/improvement sounds like something you might merge in (i.e. using integers for time is not set in stone). It works for me locally.