Skip to content

Allow retrieval of current RateLimit without actually consuming. #60551

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
heiglandreas opened this issue May 26, 2025 · 0 comments
Open

Allow retrieval of current RateLimit without actually consuming. #60551

heiglandreas opened this issue May 26, 2025 · 0 comments

Comments

@heiglandreas
Copy link
Contributor

Description

Right now the only way to get a RateLimit instance is to actually consume a token. I have so far not seen a way to get the RateLimit without that. Trying to retrieve the RateLimit without consuming a token by using 0 as parameter to RateLimiterInterface::consume() didn't work out the way I expected as - at least in the SLidingWindowLimiter the RateLimit::isAccepted() will always return true - even when there is no token available any more.

This behaviour makes sense as I am not consuming a token.

Having a way to get a RateLimit that has the isAccepted method return true or false depending on the currently available tokens would be helpful for applications that consume a token under certain circumstances along the code-path but that want to immediately at the beginning stop processing when no token is available any more. That way the application can save a lot of processing time before coming to the conclusion that the limit has been reached.

Example

public function myAction(): Request
{
    // This is what we currently try which does not work
    //$limit = $this->rateLimiter->consume(0)
    $limit = $this->rateLimiter->getCurrentLimit();
    if (! $limit->isAccepted()) {
        throw new TooManyRequestsHttpException($limit->getRetryAfter()->getTimestamp());
    }
    
    // ... do some heavy computing stuff here
    if (/* add some condition here */ true) {
        // We only want to consume a token under certain circumstances
        $this->rateLimiter->consume(1);
    }
}

Example implementation for the sliding window ratelimiter:

public function getCurrentLimit(): RateLimit
{
    $now = microtime(true);
    $hitCount = $window->getHitCount();
    $availableTokens = $this->getAvailableTokens($hitCount);
    $resetDuration = $window->calculateTimeForTokens($this->limit, $window->getHitCount());
    $resetTime = \DateTimeImmutable::createFromFormat('U', $availableTokens ? floor($now) : floor($now + $resetDuration));

    return new RateLimit($availableTokens, $resetTime, $availableTokens > 0, $this->limit));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants