fixed first algo so it adds as many tokens as needed after more than one time period has passed

This commit is contained in:
2023-08-11 08:01:18 +03:00
parent 224cc4f5ec
commit 2c9f2a30f7
3 changed files with 27 additions and 6 deletions

View File

@@ -9,7 +9,7 @@ class TooManyRequests(Exception):
pass
def token_bucket(ip: str):
def token_bucket(ip: str) -> str:
"""
Tokens are put in the bucket at preset rates periodically.
Once the bucket is full, no more tokens are added.
@@ -17,17 +17,22 @@ def token_bucket(ip: str):
"""
REFILL_EVERY_SECONDS = TIME_INTERVAL_SECONDS
NUM_TOKENS_TO_REFILL = 4
MAX_CAPACITY = 4
MAX_CAPACITY = 8
entry = TOKEN_BUCKET.get(ip)
if entry is None:
TOKEN_BUCKET[ip] = {'tokens': 4, 'last_refilled': dt.datetime.now().timestamp()}
TOKEN_BUCKET[ip] = {'tokens': MAX_CAPACITY, 'last_refilled': dt.datetime.now().timestamp()}
else:
if dt.datetime.now().timestamp() >= entry['last_refilled'] + REFILL_EVERY_SECONDS:
last_refilled = entry['last_refilled']
now = dt.datetime.now().timestamp()
if now >= last_refilled + REFILL_EVERY_SECONDS:
num_tokens_to_refill = int((now - last_refilled) // REFILL_EVERY_SECONDS * NUM_TOKENS_TO_REFILL)
entry['last_refilled'] = dt.datetime.now().timestamp()
entry['tokens'] = min(entry['tokens'] + NUM_TOKENS_TO_REFILL, MAX_CAPACITY)
entry['tokens'] = min(entry['tokens'] + num_tokens_to_refill, MAX_CAPACITY)
left = TOKEN_BUCKET[ip]['tokens']
if left == 0:
raise TooManyRequests
TOKEN_BUCKET[ip]['tokens'] -= 1

View File

@@ -1 +0,0 @@

View File

@@ -1,3 +1,20 @@
"""
TODO: implement leaky bucket
- in-app
- [x] in-memory
- [ ] redis
- [ ] redis cluster
- [ ] Flask middleware - https://flask.palletsprojects.com/en/2.1.x/quickstart/#hooking-in-wsgi-middleware
- [ ] NGINX - https://leandromoreira.com/2019/01/25/how-to-build-a-distributed-throttling-system-with-nginx-lua-redis/
- https://www.nginx.com/blog/rate-limiting-nginx/
- [ ] AWS API Gateway
- [ ] HAProxy Stick Tables - https://www.haproxy.com/blog/introduction-to-haproxy-stick-tables
- [ ] Cloudflare (Spectrum?)
TODO: implement fixed window counter
TODO: implement sliding window log
TODO: implement sliding window counter
TODO: use session IDs instead of IP address
"""
import flask as f
from . import algos