Skip to content

Instantly share code, notes, and snippets.

@coldfire-x
Created October 12, 2024 03:48
Show Gist options
  • Save coldfire-x/3fd6a7672da9ce0d060a7e937fc6b5e4 to your computer and use it in GitHub Desktop.
Save coldfire-x/3fd6a7672da9ce0d060a7e937fc6b5e4 to your computer and use it in GitHub Desktop.
cache time window such as limit request 5 per 5 mins
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