Throttling Async Functions in Python Asyncio

前端 未结 2 751
一生所求
一生所求 2020-12-04 11:53

I have a list of awaitables that I want to pass to the asyncio.AbstractEventLoop but I need to throttle the requests to a third party API.

2条回答
  •  误落风尘
    2020-12-04 12:27

    Another solution - using bounded semaphores - by a coworker, mentor, and friend, is the following:

    import asyncio
    
    
    class AsyncLeakyBucket(object):
    
        def __init__(self, max_tasks: float, time_period: float = 60, loop: asyncio.events=None):
            self._delay_time = time_period / max_tasks
            self._sem = asyncio.BoundedSemaphore(max_tasks)
            self._loop = loop or asyncio.get_event_loop()
            self._loop.create_task(self._leak_sem())
    
        async def _leak_sem(self):
            """
            Background task that leaks semaphore releases based on the desired rate of tasks per time_period
            """
            while True:
                await asyncio.sleep(self._delay_time)
                try:
                    self._sem.release()
                except ValueError:
                    pass
    
        async def __aenter__(self) -> None:
            await self._sem.acquire()
    
        async def __aexit__(self, exc_type, exc, tb) -> None:
            pass
    

    Can still be used with the same async with bucket code as in @Martijn's answer

提交回复
热议问题