Skip to content
New issue

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

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

Already on GitHub? # 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

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

No branches or pull requests

1 participant