I set the rate as 1 per second, create 2 limiters with different bucket names. Then I send the same item to both limiters. It should work, but the second item sent to the limiter2 causes BucketFullException.
This behaviour is consistent while using MemoryQueue, Fake Redis or real Redis.
I actually identified the cause of the error and there is a simple fix.
The problem is in your Limiter class:
`class Limiter:
"""Basic rate-limiter class that makes use of built-in python Queue"""
Hey there.
I think you have a bug in your code. Please consider the following scenario:
` rate = RequestRate(1, 1 * Duration.SECOND)
I set the rate as 1 per second, create 2 limiters with different bucket names. Then I send the same item to both limiters. It should work, but the second item sent to the limiter2 causes BucketFullException.
This behaviour is consistent while using MemoryQueue, Fake Redis or real Redis.
I actually identified the cause of the error and there is a simple fix.
The problem is in your Limiter class:
`class Limiter: """Basic rate-limiter class that makes use of built-in python Queue"""
Since the bucket_group is declared and instantiated outside of init it gets reused from instance to instance.
A simple fix is to initialize bucket_group in the init block like so:
def __init__( self, *rates: RequestRate, bucket_class: Type[AbstractBucket] = MemoryQueueBucket, bucket_kwargs=None, ): .... self.bucket_group = {} # <-- Fixes the issue
There is also a workaround -- once a Limiter object is created, calling bucket_group = {} works as a workaround.
Sincerely, Andrei