Skip to content

Instantly share code, notes, and snippets.

@Arfey
Created September 3, 2021 12:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Arfey/dbf6d45a9af82c08bca4296c507cddfa to your computer and use it in GitHub Desktop.
Save Arfey/dbf6d45a9af82c08bca4296c507cddfa to your computer and use it in GitHub Desktop.
#### work
import typing as t
import asyncio
RateResult = t.Callable[..., t.Coroutine[t.Any, t.Any, None]]
def rate_limit_builder(count_limit: int, time_period: int) -> RateResult:
loop = asyncio.get_event_loop()
counter = {"count": 0, "fut": loop.create_future()}
async def clean_rate_limit() -> None:
while True:
await asyncio.sleep(time_period)
if not counter['fut'].done():
counter['fut'].set_result(True)
counter["fut"] = loop.create_future()
asyncio.create_task(clean_rate_limit())
async def inner_call() -> None:
counter["count"] += 1
if counter["count"] == count_limit:
await counter["fut"]
counter["count"] = 0
return inner_call
async def test():
limit = rate_limit_builder(10, 1)
for i in range(410):
print(i)
await limit()
await asyncio.sleep(0.2)
asyncio.run(test())
### not work
import asyncio
def rate_limit_builder(max_count: int, time: int):
lock = asyncio.Lock()
counter = {"count": max_count}
async def clean_rate_limit(inner_lock):
while True:
await asyncio.sleep(time)
if inner_lock.locked():
await inner_lock.release()
asyncio.create_task(clean_rate_limit(lock))
async def inner_call(inner_lock):
counter["count"] -= 1
if counter["count"] == 0:
await inner_lock.acquire()
counter["count"] = max_count
return lambda: inner_call(lock)
async def test():
limit = rate_limit_builder(10, 1)
for i in range(40):
print(i)
await asyncio.sleep(0.1)
await limit()
asyncio.run(test())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment