TokenBucket example

public function reserve(int $tokens = 1, float $maxTime = null): Reservation
    {
        if ($tokens > $this->maxBurst) {
            throw new \InvalidArgumentException(sprintf('Cannot reserve more tokens (%d) than the burst size of the rate limiter (%d).', $tokens$this->maxBurst));
        }

        $this->lock?->acquire(true);

        try {
            $bucket = $this->storage->fetch($this->id);
            if (!$bucket instanceof TokenBucket) {
                $bucket = new TokenBucket($this->id, $this->maxBurst, $this->rate);
            }

            $now = microtime(true);
            $availableTokens = $bucket->getAvailableTokens($now);

            if ($availableTokens >= max(1, $tokens)) {
                // tokens are now available, update bucket                 $bucket->setTokens($availableTokens - $tokens);
                $bucket->setTimer($now);

                $reservation = new Reservation($nownew RateLimit($bucket->getAvailableTokens($now), \DateTimeImmutable::createFromFormat('U', floor($now)), true, $this->maxBurst));
            }
$limiter = $this->createLimiter();
        $rateLimit = $limiter->consume();
        $this->assertTrue($rateLimit->isAccepted());
        $this->assertEquals(9, $rateLimit->getRemainingTokens());
    }

    public function testBucketResilientToTimeShifting()
    {
        $serverOneClock = microtime(true) - 1;
        $serverTwoClock = microtime(true) + 1;

        $bucket = new TokenBucket('id', 100, new Rate(\DateInterval::createFromDateString('5 minutes'), 10)$serverTwoClock);
        $this->assertSame(100, $bucket->getAvailableTokens($serverTwoClock));
        $this->assertSame(100, $bucket->getAvailableTokens($serverOneClock));

        $bucket = new TokenBucket('id', 100, new Rate(\DateInterval::createFromDateString('5 minutes'), 10)$serverOneClock);
        $this->assertSame(100, $bucket->getAvailableTokens($serverTwoClock));
        $this->assertSame(100, $bucket->getAvailableTokens($serverOneClock));
    }

    public function testPeekConsume()
    {
        $limiter = $this->createLimiter();

        
Home | Imprint | This part of the site doesn't use cookies.