使用 asyncio.gather() 的协程/期货的经过时间

Posted

技术标签:

【中文标题】使用 asyncio.gather() 的协程/期货的经过时间【英文标题】:Elapsed time of coroutines/futures using asyncio.gather() 【发布时间】:2021-07-22 14:47:00 【问题描述】:

我有一个异步查询列表,我正在使用 asyncio.gather() 收集这些查询并使用 asyncio.run_until_complete() 等待。比如:

queries = [
  async_query_a(),
  async_query_b()
]

loop = asyncio.get_event_loop()
tasks = asyncio.gather(*queries)
results = loop.run_until_complete(tasks)

我想知道每个查询的“等待时间”。类似于 @log_performance 包装器的东西,它记录未来/协程完成的经过时间。

【问题讨论】:

【参考方案1】:

这是timecoro 对协程函数计时的示例实现。

import asyncio
import functools
import logging
import random
import time

def timecoro(corofn):
    @functools.wraps(corofn)
    async def wrapper(*args, **kwargs):
        start = time.time()
        try:
            result = await corofn(*args, **kwargs)
        except Exception:
            finish = time.time() - start
            logging.info('%s failed in %.2f', corofn, finish)
            raise
        else:
            finish = time.time() - start
            logging.info('%s succeeded in %.2f', corofn, finish)
            return result            
        
    return wrapper

@timecoro
async def async_query_a():
    await asyncio.sleep(random.randint(0, 4))

@timecoro    
async def async_query_b():
    await asyncio.sleep(random.randint(0, 4))
    raise RuntimeError

async def main():
    queries = [
        async_query_a(),
        async_query_b(),
    ]
    await asyncio.gather(*queries)

if __name__ == '__main__':
    logging.basicConfig(level='INFO')
    asyncio.run(main())

【讨论】:

以上是关于使用 asyncio.gather() 的协程/期货的经过时间的主要内容,如果未能解决你的问题,请参考以下文章

asyncio.gather() 在具有协程字段的 dict 列表上?

在超时中包装 asyncio.gather

Python 的 asyncio.gather() 似乎没有异步运行任务

如何在 Python 3.8 中为 asyncio.gather 构建任务列表

Kotlin 协程协程取消 ③ ( finally 释放协程资源 | 使用 use 函数执行 Closeable 对象释放资源操作 | 构造无法取消的协程任务 | 构造超时取消的协程任务 )

Kotlin 协程协程取消 ③ ( finally 释放协程资源 | 使用 use 函数执行 Closeable 对象释放资源操作 | 构造无法取消的协程任务 | 构造超时取消的协程任务 )