Skip to content

Commit 43881e7

Browse files
committed
Introduced RateLimiter component
1 parent e6e1ca3 commit 43881e7

20 files changed

+830
-3
lines changed

src/Symfony/Component/Lock/CHANGELOG.md

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
CHANGELOG
22
=========
33

4+
5.2.0
5+
-----
6+
7+
* added `NoLock`
8+
49
5.1.0
510
-----
611

@@ -19,10 +24,10 @@ CHANGELOG
1924
* added InvalidTtlException
2025
* deprecated `StoreInterface` in favor of `BlockingStoreInterface` and `PersistingStoreInterface`
2126
* `Factory` is deprecated, use `LockFactory` instead
22-
* `StoreFactory::createStore` allows PDO and Zookeeper DSN.
23-
* deprecated services `lock.store.flock`, `lock.store.semaphore`, `lock.store.memcached.abstract` and `lock.store.redis.abstract`,
27+
* `StoreFactory::createStore` allows PDO and Zookeeper DSN.
28+
* deprecated services `lock.store.flock`, `lock.store.semaphore`, `lock.store.memcached.abstract` and `lock.store.redis.abstract`,
2429
use `StoreFactory::createStore` instead.
25-
30+
2631
4.2.0
2732
-----
2833

src/Symfony/Component/Lock/NoLock.php

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Lock;
13+
14+
/**
15+
* A non locking lock.
16+
*
17+
* This is used when no mutex is required for this rate limiter
18+
* (e.g. when using in memory or session storage).
19+
*
20+
* @author Wouter de Jong <wouter@wouterj.nl>
21+
*
22+
* @final
23+
*/
24+
class NoLock implements LockInterface
25+
{
26+
public function acquire(bool $blocking = false): bool
27+
{
28+
return true;
29+
}
30+
31+
public function refresh(float $ttl = null)
32+
{
33+
}
34+
35+
public function isAcquired(): bool
36+
{
37+
return true;
38+
}
39+
40+
public function release()
41+
{
42+
}
43+
44+
public function isExpired(): bool
45+
{
46+
return false;
47+
}
48+
49+
public function getRemainingLifetime(): ?float
50+
{
51+
return null;
52+
}
53+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
/Tests export-ignore
2+
/phpunit.xml.dist export-ignore
3+
/.gitattributes export-ignore
4+
/.gitignore export-ignore
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
composer.lock
2+
phpunit.xml
3+
vendor/
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
CHANGELOG
2+
=========
3+
4+
5.2.0
5+
-----
6+
7+
* added the component
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\RateLimiter\Exception;
13+
14+
/**
15+
* @author Wouter de Jong <wouter@wouterj.nl>
16+
*/
17+
class MaxWaitDurationExceededException extends \RuntimeException
18+
{
19+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
Copyright (c) 2016-2020 Fabien Potencier
2+
3+
Permission is hereby granted, free of charge, to any person obtaining a copy
4+
of this software and associated documentation files (the "Software"), to deal
5+
in the Software without restriction, including without limitation the rights
6+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
copies of the Software, and to permit persons to whom the Software is furnished
8+
to do so, subject to the following conditions:
9+
10+
The above copyright notice and this permission notice shall be included in all
11+
copies or substantial portions of the Software.
12+
13+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19+
THE SOFTWARE.
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\RateLimiter;
13+
14+
use Symfony\Component\RateLimiter\Exception\MaxWaitDurationExceededException;
15+
16+
/**
17+
* @author Wouter de Jong <wouter@wouterj.nl>
18+
*/
19+
interface LimiterInterface
20+
{
21+
/**
22+
* Use this method if you intend to wait until the required number
23+
* of tokens is available.
24+
*
25+
* The reserved tokens will be taken into account when calculating
26+
* future token consumptions. Do not use this method if you intend
27+
* to skip this process.
28+
*
29+
* @param int $tokens the number of tokens required
30+
* @param float $maxTime maximum accepted waiting time in seconds
31+
*
32+
* @throws MaxWaitDurationExceededException if $maxTime is set and the process needs to wait longer than its value (in seconds)
33+
*/
34+
public function reserve(int $tokens = 1, ?float $maxTime = null): Reservation;
35+
36+
/**
37+
* Use this method if you intend to drop if the required number
38+
* of tokens is unavailable.
39+
*
40+
* @param int $tokens the number of tokens required
41+
*/
42+
public function consume(int $tokens = 1): bool;
43+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\RateLimiter;
13+
14+
/**
15+
* Implements a non limiting limiter.
16+
*
17+
* This can be used in cases where an implementation requires a
18+
* limiter, but no rate limit should be enforced.
19+
*
20+
* @author Wouter de Jong <wouter@wouterj.nl>
21+
*/
22+
class NoLimiter implements LimiterInterface
23+
{
24+
public function reserve(int $tokens = 1, ?float $maxTime = null): Reservation
25+
{
26+
return new Reservation($tokens, microtime(true));
27+
}
28+
29+
public function consume(int $tokens = 1): bool
30+
{
31+
return true;
32+
}
33+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
Rate Limiter Component
2+
======================
3+
4+
The Rate Limiter component provides a Token Bucket implementation to
5+
rate limit input and output in your application.
6+
7+
Getting Started
8+
---------------
9+
10+
```
11+
$ composer require symfony/rate-limiter
12+
```
13+
14+
```php
15+
use Symfony\Component\RateLimiter\Rate;
16+
use Symfony\Component\RateLimiter\Storage\InMemoryStorage;
17+
use Symfony\Component\RateLimiter\TokenBucket;
18+
use Symfony\Component\RateLimiter\TokenBucketLimiter;
19+
20+
$limiter = new TokenBucketLimiter(
21+
new TokenBucket($clientIp, 10, Rate::perMinute(5)),
22+
new InMemoryStorage()
23+
);
24+
25+
// blocks until 1 token is free to use for this process
26+
$limiter->reserve(1)->wait();
27+
// ... execute the code
28+
29+
// only claims 1 token if it's free at this moment (usefull if you plan to skip this process)
30+
if ($limiter->consume(1)) {
31+
// ... execute the code
32+
}
33+
```
34+
35+
Resources
36+
---------
37+
38+
* [Contributing](https://symfony.com/doc/current/contributing/index.html)
39+
* [Report issues](https://github.com/symfony/symfony/issues) and
40+
[send Pull Requests](https://github.com/symfony/symfony/pulls)
41+
in the [main Symfony repository](https://github.com/symfony/symfony)

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy