我正在使用asyncio
和python3.5.1
,我有一个实用程序函数,可以将同步方法转换为异步方法。我传递了多个阻塞函数并等待其结果超时。我使用超时,因为我不想阻止整个过程。
让我们假设,我们有系统搜索的东西。它搜索不同的数据源并将结果合并为一个,并以毫秒为单位将其响应给最终用户。不要在特定时间(超时)阻止我们的最终用户,我想为每个搜索源添加一些超时。我已经使用下面的代码完成了这项工作。但我的问题是,有没有办法处理超时问题并生成某种电子邮件警报等等。因为我想监视它们并试图找出最新情况,而我的最终用户对系统搜索速度没有任何问题。我宁愿忽略一点准确性,而不是那么慢地进行搜索。缓慢的问题可能会扼杀我们。
def run_blocking_tasks(func_with_args, wait=False, timeout=None):
async def _execute(func_with_args, wait, timeout):
logger.debug('creating executor tasks')
executor = ThreadPoolExecutor(max_workers=len(func_with_args),)
loop = asyncio.get_event_loop()
blocking_tasks = [loop.run_in_executor(executor, func_call[0], *func_call[1]) for func_call in func_with_args]
logger.debug('waiting for executor tasks')
completed, pending = await asyncio.wait(blocking_tasks, timeout=timeout, return_when=asyncio.ALL_COMPLETED)
if wait:
return [t.result() for t in completed]
loop = asyncio.get_event_loop()
return loop.run_until_complete(_execute(func_with_args, wait, timeout))
我将此函数称为;
run_blocking_tasks(
[
(fast_source1.search, [arg1, arg2, arg3]),
(fast_source2.search, [arg1, arg2, arg3]),
(slow_source1.search, [arg1, arg2, arg3]),
],timeout=1.0)
此代码将正常运行。它将及时作为我们的超时响应,无论我的消息来源发生了什么。但是我需要做一些事情,(可能记录到数据库或发送电子邮件,我不知道),超时发生。
我看到了asyncio.wait_for
,但我想,它会取消所有内容并引发TimeourError。我不想取消任何东西。我希望我的成功结果及时响应,以保证一段时间向我的最终用户呈现。