@@ -124,12 +124,13 @@ the number of requests to the API::
124
124
125
125
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
126
126
use Symfony\Component\HttpKernel\Exception\TooManyRequestsHttpException;
127
- use Symfony\Component\RateLimiter\Limiter ;
127
+ use Symfony\Component\RateLimiter\RateLimiter ;
128
128
129
129
class ApiController extends AbstractController
130
130
{
131
131
// 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)
133
134
{
134
135
// create a limiter based on a unique identifier of the client
135
136
// (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::
158
159
for the :ref: `kernel.request event <component-http-kernel-kernel-request >`
159
160
and check the rate limiter once for all requests.
160
161
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::
163
168
164
169
// src/Controller/ApiController.php
165
170
namespace App\Controller;
166
171
167
172
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
168
173
use Symfony\Component\HttpFoundation\Request;
169
- use Symfony\Component\RateLimiter\Limiter ;
174
+ use Symfony\Component\RateLimiter\RateLimiter ;
170
175
171
176
class ApiController extends AbstractController
172
177
{
173
- public function registerUser(Request $request, Limiter $authenticatedApiLimiter)
178
+ public function registerUser(Request $request, RateLimiter $authenticatedApiLimiter)
174
179
{
175
180
$apiKey = $request->headers->get('apikey');
176
181
$limiter = $authenticatedApiLimiter->create($apiKey);
177
182
178
183
// 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();
183
189
184
190
// ...
185
191
}
186
192
187
193
// ...
188
194
}
189
195
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
+
190
215
Rate Limiter Storage and Locking
191
216
--------------------------------
192
217
0 commit comments