Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expire time of Multiple ratelimit on same view not seem correct. #288

Open
towfiq007 opened this issue Jun 10, 2023 · 0 comments
Open

Expire time of Multiple ratelimit on same view not seem correct. #288

towfiq007 opened this issue Jun 10, 2023 · 0 comments

Comments

@towfiq007
Copy link

towfiq007 commented Jun 10, 2023

I tried to use django-ratelimit to ratelimit same view with multiple limits:

def multiple_rate_limit(key, rates):
    """
    Custom decorator to apply multiple rate limits to a view.
    'rates' should be a list of rate limit strings, such as ['5/m', '100/h', '1000/d'].
    """
    def decorator(view_func):
        decorated_view = view_func
        for rate in rates:
            decorated_view = ratelimit(key=key, rate=rate)(decorated_view)
        return decorated_view
    return decorator


@multiple_rate_limit(key='user_or_ip', rates=['10/m', '300/30d'])
def home(request): #new
    return HttpResponse('<h1>Django Include URLs</h1>')

After calling the view first time the expire time is as below:
select * from cache_djrate ;
cache_key | value | expires
----------------------------------------+----------+------------------------
:1:rl:45b5d276e180f5b4f5d566ef01cfd472 | gAVLAS4= | 2023-07-10 17:40:38+06
:1:rl:41e758c64a2f25fe69295b778ca19be5 | gAVLAS4= | 2023-06-10 17:41:38+06
(2 rows)

So the monthly limit reflects correctly on expire time in the first row.

But, after calling the view again, these entries are manipulated as below:
select * from cache_djrate ;
cache_key | value | expires
----------------------------------------+----------+------------------------
:1:rl:45b5d276e180f5b4f5d566ef01cfd472 | gAVLAi4= | 2023-06-10 17:41:46+06
:1:rl:41e758c64a2f25fe69295b778ca19be5 | gAVLAi4= | 2023-06-10 17:41:46+06
(2 rows)

So, the first row expire time is no longer 1 month as expected.
Please check it.

Generally, multiple ratelimit this way is working and can block if count > limit.
But, the cache deletion mechanism seem to solely depend on expire time and number of entries with ratio.
So, if the expire time is 1 minute instead of 1 month as shown above, it might be deleted erroneously.

Similar expire time showing when only using monthly limit instead of multiple rate limits:

@ratelimit(group=None, key='user', rate='300/30d', method=ALL, block=True)
def home(request): #new
    return HttpResponse('<h1>Django Include URLs</h1>')

After calling view the first time:
djrate=# select * from cache_djrate ;
cache_key | value | expires
----------------------------------------+----------+------------------------
:1:rl:5d211ec5fef5dc09ea129067c38e9646 | gAVLAS4= | 2023-07-10 18:13:28+06
(1 row)

After calling the view the second time:
djrate=# select * from cache_djrate ;
cache_key | value | expires
----------------------------------------+----------+------------------------
:1:rl:5d211ec5fef5dc09ea129067c38e9646 | gAVLAi4= | 2023-06-10 18:14:29+06

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant