使用asyncio在异常后重新排队期货

时间:2017-06-10 20:36:57

标签: python asynchronous task future

我试图找出如何重新排队已超时的异步DNS请求(我使用uvloop和aiodns模块)。

这是我设置循环的代码:

async def lookup(name):
    with (await sem):
        response = await resolver.query(name, 'A')
        return response

此函数执行查找:

for n in names:
    host = '{}.{}'.format(n, domain)
    task = asyncio.ensure_future(lookup(host))
    tasks.append(task)
    task.add_done_callback(functools.partial(got_result, host))

我在一个包含要查找的名称的文件中读取并设置了包含回调以处理结果的任务:

print("Looking up {} subdomains...".format(len(names)))
loop.run_until_complete(asyncio.wait(tasks))
loop.close()

然后启动查找队列。

got_result

::before回调中,我测试future.exception()并处理它(如果有),如果没有将结果打印到屏幕。我不喜欢的一些例外(即找不到域名),但其他一些例如超时我想重新排队项目。是否有一种简单的方法可以将未来添加回循环以进行另一次尝试,或者我是否需要为此设置单独的功能并手动重新添加任务?

感谢您的帮助。

1 个答案:

答案 0 :(得分:4)

  

问题:...但其他人喜欢超时我想重新排队该项目。

重新排队任务可能会导致死锁 而不是重新排队任务,举行任务,例如:

async def lookup(name):
    with (await sem):
        retries = 0
        while retries <= 5:
            try:
                response = await resolver.query(name, 'A')
                break
            except TimeoutError:
                retries += 1
                yield from asyncio.sleep(1)

        return response