Created
October 12, 2024 03:48
-
-
Save coldfire-x/3fd6a7672da9ce0d060a7e937fc6b5e4 to your computer and use it in GitHub Desktop.
cache time window such as limit request 5 per 5 mins
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def _get_window(value, period): | |
""" | |
Given a value, and time period return when the end of the current time | |
period for rate evaluation is. | |
""" | |
ts = int(time.time()) | |
if period == 1: | |
return ts | |
if not isinstance(value, bytes): | |
value = value.encode('utf-8') | |
# This logic determines either the last or current end of a time period. | |
# Subtracting (ts % period) gives us the a consistent edge from the epoch. | |
# We use (zlib.crc32(value) % period) to add a consistent jitter so that | |
# all time periods don't end at the same time. | |
w = ts - (ts % period) + (zlib.crc32(value) % period) | |
if w < ts: | |
return w + period | |
return w | |
# [email protected]:jsocol/django-ratelimit.git | |
""" | |
Certainly! Let's break down this `_get_window` function, which is an important part of the rate limiting mechanism: | |
```python:django_ratelimit/core.py | |
def _get_window(value, period): | |
""" | |
Given a value, and time period return when the end of the current time | |
period for rate evaluation is. | |
""" | |
ts = int(time.time()) | |
if period == 1: | |
return ts | |
if not isinstance(value, bytes): | |
value = value.encode('utf-8') | |
# This logic determines either the last or current end of a time period. | |
# Subtracting (ts % period) gives us the a consistent edge from the epoch. | |
# We use (zlib.crc32(value) % period) to add a consistent jitter so that | |
# all time periods don't end at the same time. | |
w = ts - (ts % period) + (zlib.crc32(value) % period) | |
if w < ts: | |
return w + period | |
return w | |
``` | |
Here's what this function does: | |
1. It takes two parameters: | |
- `value`: A unique identifier for the rate limit (e.g., IP address, user ID) | |
- `period`: The duration of the rate limit window in seconds | |
2. It gets the current timestamp: | |
```python | |
ts = int(time.time()) | |
``` | |
3. If the period is 1 second, it simply returns the current timestamp: | |
```python | |
if period == 1: | |
return ts | |
``` | |
4. It ensures the `value` is in bytes format: | |
```python | |
if not isinstance(value, bytes): | |
value = value.encode('utf-8') | |
``` | |
5. The core of the function calculates the end of the current time window: | |
```python | |
w = ts - (ts % period) + (zlib.crc32(value) % period) | |
``` | |
This does a few things: | |
- `ts % period`: This gives us the number of seconds into the current period. | |
- `ts - (ts % period)`: This rounds down to the start of the current period. | |
- `zlib.crc32(value) % period`: This adds a consistent "jitter" based on the value. | |
6. Finally, it ensures the calculated window end is in the future: | |
```python | |
if w < ts: | |
return w + period | |
return w | |
``` | |
The purpose of this function is to create a "sliding window" for rate limiting that's unique to each `value` (e.g., each user or IP address). The jitter helps distribute the load on the system by ensuring that not all rate limit windows end at the same time for different users or IPs. | |
This approach allows for more even distribution of rate limit checks and resets, which can be beneficial for system performance, especially under high load. | |
""" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment