2017-06-10 5 views
0

Ich versuche herauszufinden, wie einige asynchrone DNS-Anfragen, die abgelaufen sind (ich benutze uvloop und aiodns-Module) in die Warteschlange.Re-Queue-Futures nach Ausnahme mit asyncio

Hier ist der Code, den ich die Schleife eingerichtet mit:

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

Diese Funktion führt die Suche:

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

ich in einer Datei einschließlich nachschlagen enthält Namen lesen und einrichten Aufgaben ein Rückruf, um mit den Ergebnissen umzugehen:

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)) 

Und die Nachschlagewarteschlange starten.

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

Im got_result Rückruf ich dann testen für future.exception() und damit umgehen, wenn es einen gibt, und wenn nicht das Ergebnis drucken zu screenen. Einige der Ausnahmen, die mir gut sind (d. H. Domainname nicht gefunden), aber andere wie ein Timeout Ich möchte das Element erneut in die Warteschlange stellen. Gibt es eine einfache Möglichkeit, die Zukunft für einen anderen Versuch wieder in die Schleife einzufügen, oder muss ich dafür eine separate Funktion einrichten und eine Aufgabe manuell hinzufügen?

Danke für Ihre Hilfe.

Antwort

2

Frage: ... aber andere wie ein Timeout Ich möchte den Artikel neu Warteschlange.

Requeue der Task konnte zu einem Deadlock führen.
Statt Requeue der Aufgabe, halten Sie die Aufgabe, zum Beispiel:

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

Vielen Dank, ich habe nie darüber nachgedacht, auf diese Weise mit ihm zu tun. Ich werde es versuchen. – Blark