可用于消费任务场景,单线程异步并发处理任务,最大性能比消费
主调度函数如下
async def run(self):
"""异步主循环处理任务
持续从队列获取任务并处理,通过信号量控制并发数,
无需等待当前批次任务全部完成即可处理新任务
self.process_task 为单个任务处理函数
self.semaphore_num 为最大并发处理数
self.baseinfo.task_queue 为取任务类(此处使用redis)
"""
async with aiohttp.ClientSession() as session:
# 异步请求session(可选)
self.session = session
# 用于追踪正在执行的任务
running_tasks = set()
while True:
if running_tasks:
await asyncio.wait(
running_tasks, return_when=asyncio.FIRST_COMPLETED, timeout=2,
)
elif self.baseinfo.task_queue.num_of_tasks() == 0:
# 队列无任务
await asyncio.sleep(0.2)
# 清理已完成的任务
running_tasks = {task for task in running_tasks if not task.done()}
# 当前正在执行的任务数量低于最大并发数时,尝试添加新任务
empty_slots = self.semaphore_num - len(running_tasks)
if empty_slots == 0:
# task队列必不为空
continue
tasks = self.baseinfo.task_queue.fetch_tasks(empty_slots)
for company_id, score in tasks:
# self.process_task 为单个任务处理函数
task = asyncio.create_task(self.process_task(company_id))
running_tasks.add(task)
其余函数正常使用async即可,无需限制并发