Closed RafaB6n closed 1 year ago
it was an error because in your code, try-acquire is indeed not awaitable because none of the underlying logic is async - and you cannot "await" a synchronous code.
therefore it is not a bug.
if you like to await, you have to use something async inside the limiter (bucket, clock etc)
to make your code work, just remove the await before limiter.try_acquire
Should we this from the README then?
Link
Edit: Do you mean something like this?
import asyncio
from pyrate_limiter import Duration, Rate, Limiter, BucketAsyncWrapper, \
InMemoryBucket, TimeClock
from pyrate_limiter.limiter import SingleBucketFactory
async def main():
rate = Rate(5, Duration.SECOND * 2)
bucket = BucketAsyncWrapper(InMemoryBucket([rate]))
bucket_factory = SingleBucketFactory(bucket, TimeClock()) # Or is TimeAsyncClock needed here?
limiter = Limiter(bucket_factory)
await limiter.try_acquire('name', 1)
asyncio.run(main())
If yes, WDYT of adding this to the README?
oh i think you are misunderstanding.
i wrote "if your bucket backend is async, you can use await".
but in the code, your bucket backend is InMemoryBucket and it is not async, so using await is not possible
Regarding BucketAsyncWrapper, it is meant for testing only and it should not be used for production.
Is there a suggested way to have a simple async capable in-memory bucket (for production use)?
Is there a suggested way to have a simple async capable in-memory bucket (for production use)?
you can use TimeAsyncClock. But Im not sure why you want to do it.
My aim is to have a simple way to be able to await try_acquire in an async function. Such that an async task is suspended, while it waits for try_acquire to allow it to continue.
await limiter.try_acquire(...)
Also:
Is there a suggested way to have a simple async capable in-memory bucket (for production use)?
you can use TimeAsyncClock. But Im not sure why you want to do it.
Are you sure about using TimeAsyncClock? It also seems to intended for testing only as well: https://github.com/vutran1710/PyrateLimiter/blob/master/pyrate_limiter/clocks.py#L25-L26
My aim is to have a simple way to be able to await try_acquire in an async function. Such that an async task is suspended, while it waits for try_acquire to allow it to continue.
await limiter.try_acquire(...)
Also:
Is there a suggested way to have a simple async capable in-memory bucket (for production use)?
you can use TimeAsyncClock. But Im not sure why you want to do it.
Are you sure about using TimeAsyncClock? It also seems to intended for testing only as well:
https://github.com/vutran1710/PyrateLimiter/blob/master/pyrate_limiter/clocks.py#L25-L26
async & await are only meaningful when you deal with io-bound actions. in-memory-bucket is not io-bound because it does not make any network call other than processing computation in memory. so it does not make sense to await limiter using such bucket
of course, you still can write
async def example(): limiter.try_acquire("item")
TimeAsyncClock is indeed made for testing, but it still can be used in your case without affecting performance.
Ok, thanks a lot. Just to verify: This would be a possible way for my use case, (also for prod use)?
import asyncio
from pyrate_limiter import Duration, Rate, Limiter, InMemoryBucket, TimeAsyncClock
from pyrate_limiter.limiter import SingleBucketFactory
async def main():
rate = Rate(5, Duration.SECOND * 2)
bucket_factory = SingleBucketFactory(InMemoryBucket([rate]), TimeAsyncClock())
limiter = Limiter(bucket_factory)
await limiter.try_acquire('name', 1)
asyncio.run(main())
Ok, thanks a lot.
Just to verify: This would be a possible way for my use case, (also for prod use)?
import asyncio from pyrate_limiter import Duration, Rate, Limiter, InMemoryBucket, TimeAsyncClock from pyrate_limiter.limiter import SingleBucketFactory async def main(): rate = Rate(5, Duration.SECOND * 2) bucket_factory = SingleBucketFactory(InMemoryBucket([rate]), TimeAsyncClock()) limiter = Limiter(bucket_factory) await limiter.try_acquire('name', 1) asyncio.run(main())
yes
At the moment when I run this:
I get this error:
Not sure if this is all that's needed to fix it, but for me it seems to work.