2017-06-10 36 views
0

我試圖找出如何重新排隊已超時(我使用uvloop和aiodns模塊)一些異步DNS請求異常後。重新排隊期貨與ASYNCIO

下面是我設置的循環與代碼:

asyncio.set_event_loop_policy(uvloop.EventLoopPolicy()) 
loop = asyncio.get_event_loop() 
resolver = aiodns.DNSResolver(loop=loop) 
sem = asyncio.Semaphore(MAX_COUNT) 

此功能進行查找:

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回調然後我測試future.exception()和對付它,如果有一個,如果沒有打印出結果篩選。有些我很好(未找到即域名)的異常,但其他人一樣超時我要重新排隊的項目。有一個簡單的單向增加未來回到循環闖闖或者我需要建立一個獨立的函數,該函數和手動重新添加任務?

感謝您的幫助。

回答

2

問題:......但其他人一樣超時我要重新排隊的項目。

重新排隊的任務可能會導致死鎖
而不是重新排隊的任務,保持任務,例如:

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    
+0

非常感謝,我從來沒有想過它以這種方式處理。我會給它一個鏡頭。 – Blark