Skip to content

Commit 72ff903

Browse files
committed
Document reserve() method and rename to RateLimiter
1 parent 0434fbb commit 72ff903

File tree

1 file changed

+35
-10
lines changed

1 file changed

+35
-10
lines changed

rate_limiter.rst

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
190215
Rate Limiter Storage and Locking
191216
--------------------------------
192217

0 commit comments

Comments
 (0)