Description
Description
Seems the new feature RateLimiter has been designed to limit the number of request that is coming to an application (inbound). What do you think to use this new feature to control the RateLimit for http request outbound? In order to never reach the rate limit when we are calling an external API which limit the number of request per second, per minute...
Example
I had the idea to use that because existing rate limiter middleware for Guzzle (i.e. https://github.com/spatie/guzzle-rate-limiter-middleware) does not manage "shared rate limiter" across several processes running in same time in parallel. Seems symfony/rate-limiter manages that natively. I tested and seems it works but I would like feedback from experts :-).
The code of the RateLimiterMiddleware for guzzle:
<?php
namespace App\GuzzleMiddleware\RateLimiterMiddleware;
use Closure;
use Psr\Http\Message\RequestInterface;
use Symfony\Component\RateLimiter\RateLimiterFactory;
class RateLimiter
{
/** @var RateLimiterFactory */
protected $guzzleRateLimiter;
/**
* RateLimiter constructor.
* @param RateLimiterFactory $guzzleRateLimiter
*/
public function __construct(RateLimiterFactory $guzzleRateLimiter)
{
$this->guzzleRateLimiter = $guzzleRateLimiter;
}
/**
* @param callable $handler
* @return Closure
*/
public function __invoke(callable $handler): Closure
{
return function (RequestInterface $request, array $options) use ($handler) {
$limiter = $this->guzzleRateLimiter->create('custom-guzzle-rate-limiter');
while(!$limiter->consume()->isAccepted()){
sleep(1);
}
return $handler($request, $options);
};
}
}
How to add the middleware to guzzle (inside services.yaml:
GuzzleMiddleware\GuzzleLimiterMiddleware\RateLimiter:
class: App\GuzzleMiddleware\RateLimiterMiddleware\RateLimiter
GuzzleHttp\HandlerStack:
class: GuzzleHttp\HandlerStack
factory: [ 'GuzzleHttp\HandlerStack', create ]
calls:
- [ push, [ '@log_middleware', 'log' ] ]
- [ push, [ '@GuzzleMiddleware\GuzzleLimiterMiddleware\RateLimiter' ] ]