Ich möchte mich sehr schnell mit einer Liste von vielen verschiedenen Seiten verbinden. Ich benutze asyncio, um dies in einer asynchronen Art und Weise zu tun und jetzt hinzufügen ein Timeout für wenn Verbindungen ignoriert werden sollen, wenn sie zu lange dauern, um zu antworten.Wie kann ich ein Verbindungstimeout mit asyncio hinzufügen?
Wie implementiere ich das?
import ssl
import asyncio
from contextlib import suppress
from concurrent.futures import ThreadPoolExecutor
import time
@asyncio.coroutine
def run():
while True:
host = yield from q.get()
if not host:
break
with suppress(ssl.CertificateError):
reader, writer = yield from asyncio.open_connection(host[1], 443, ssl=True) #timout option?
reader.close()
writer.close()
@asyncio.coroutine
def load_q():
# only 3 entries for debugging reasons
for host in [[1, 'python.org'], [2, 'qq.com'], [3, 'google.com']]:
yield from q.put(host)
for _ in range(NUM):
q.put(None)
if __name__ == "__main__":
NUM = 1000
q = asyncio.Queue()
loop = asyncio.get_event_loop()
loop.set_default_executor(ThreadPoolExecutor(NUM))
start = time.time()
coros = [asyncio.async(run()) for i in range(NUM)]
loop.run_until_complete(load_q())
loop.run_until_complete(asyncio.wait(coros))
end = time.time()
print(end-start)
(Auf einer Nebenbemerkung: Hat jemand eine Idee, wie diese zu optimieren?)
Sie haben vergessen, die Aufrufe von 'q.put (None)' in 'load_q' zu" ergeben ", so dass dieser Code nicht wie derzeit geschrieben funktioniert. – dano
Sie brauchen hier nicht Reader, Writer. Sie könnten 'asyncio.create_connection' mit' Protocol' verwenden, das nichts tut (es schließt die Netzwerkverbindung, sobald es eingerichtet ist). Hier ist [Codebeispiel, dass ich auf Million Alexa Website-Liste oben versucht habe] (http://StackOverflow.com/a/20722204/4279) (es könnte etwas veraltet sein, zB, es verwendet nicht einige Convience-Funktionen wie ' asyncio.wait_for() '). Es verwendet einen einzelnen Thread und öffnet sich zu 'limit' ssl Verbindungen. – jfs