Bla*_*ark 1 python asynchronous future task
我想弄清楚如何重新排队一些已超时的异步 DNS 请求(我正在使用 uvloop 和 aiodns 模块)。
这是我设置循环的代码:
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
loop = asyncio.get_event_loop()
resolver = aiodns.DNSResolver(loop=loop)
sem = asyncio.Semaphore(MAX_COUNT)
Run Code Online (Sandbox Code Playgroud)
此函数执行查找:
async def lookup(name):
with (await sem):
response = await resolver.query(name, 'A')
return response
Run Code Online (Sandbox Code Playgroud)
我读入了一个包含名称的文件以查找和设置任务,包括处理结果的回调:
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))
Run Code Online (Sandbox Code Playgroud)
并启动查找队列。
print("Looking up {} subdomains...".format(len(names)))
loop.run_until_complete(asyncio.wait(tasks))
loop.close()
Run Code Online (Sandbox Code Playgroud)
在got_result回调中,我然后测试 future.exception() 并处理它,如果有,如果没有,则将结果打印到屏幕上。我可以接受一些例外情况(即找不到域名),但其他人喜欢超时,我想重新排队项目。是否有一种简单的方法可以将未来添加回循环以进行另一次尝试,还是我需要为此设置单独的功能并手动重新添加任务?
谢谢你的帮助。
问题:...但其他人喜欢超时我想重新排队项目。
重新排队任务可能会导致死锁。
保持任务,而不是重新排队任务,例如:
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
Run Code Online (Sandbox Code Playgroud)