@@ -124,12 +124,13 @@ the number of requests to the API::
124124
125125 use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
126126 use Symfony\Component\HttpKernel\Exception\TooManyRequestsHttpException;
127- use Symfony\Component\RateLimiter\Limiter ;
127+ use Symfony\Component\RateLimiter\RateLimiter ;
128128
129129 class ApiController extends AbstractController
130130 {
131131 // the variable name must be: "rate limiter name" + "limiter" suffix
132- public function index(Limiter $anonymousApiLimiter)
132+ // if you're using autowiring for your services
133+ public function index(RateLimiter $anonymousApiLimiter)
133134 {
134135 // create a limiter based on a unique identifier of the client
135136 // (e.g. the client's IP address, a username/email, an API key, etc.)
@@ -158,35 +159,59 @@ the number of requests to the API::
158159 for the :ref: `kernel.request event <component-http-kernel-kernel-request >`
159160 and check the rate limiter once for all requests.
160161
161- In other scenarios you may want instead to wait as long as needed until a new
162- token is available. In those cases, use the ``wait() `` method::
162+ Wait until a Token is Available
163+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
164+
165+ Instead of dropping a request or process when the limit has been reached,
166+ you might want to wait until a new token is available. This can be achieved
167+ using the ``reserve() `` method::
163168
164169 // src/Controller/ApiController.php
165170 namespace App\Controller;
166171
167172 use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
168173 use Symfony\Component\HttpFoundation\Request;
169- use Symfony\Component\RateLimiter\Limiter ;
174+ use Symfony\Component\RateLimiter\RateLimiter ;
170175
171176 class ApiController extends AbstractController
172177 {
173- public function registerUser(Request $request, Limiter $authenticatedApiLimiter)
178+ public function registerUser(Request $request, RateLimiter $authenticatedApiLimiter)
174179 {
175180 $apiKey = $request->headers->get('apikey');
176181 $limiter = $authenticatedApiLimiter->create($apiKey);
177182
178183 // this blocks the application until the given number of tokens can be consumed
179- do {
180- $limit = $limiter->consume(1);
181- $limit->wait();
182- } while (!$limit->isAccepted());
184+ $limiter->reserve(1)->wait();
185+
186+ // optional, pass a maximum wait time (in seconds), a MaxWaitDurationExceededException
187+ // is thrown if the process has to wait longer. E.g. to wait at most 20 seconds:
188+ //$limiter->reserve(1, 20)->wait();
183189
184190 // ...
185191 }
186192
187193 // ...
188194 }
189195
196+ The ``reserve() `` method is able to reserve a token in the future. Only use
197+ this method if you're planning to wait, otherwise you will block other
198+ processes by reserving unused tokens.
199+
200+ .. note ::
201+
202+ Not all strategies allow reservering tokens in the future. These
203+ strategies may throw an ``ReserveNotSupportedException `` when calling
204+ ``reserve() ``.
205+
206+ In these cases, you can use ``consume() `` together with ``wait() ``, but
207+ there is no guarantee that a token is available after the wait::
208+
209+ // ...
210+ do {
211+ $limit = $limiter->consume(1);
212+ $limit->wait();
213+ } while (!$limit->isAccepted());
214+
190215Rate Limiter Storage and Locking
191216--------------------------------
192217
0 commit comments