Использую сейчас следующий код (пожалуйста, не обращайте внимание на форматирование и качество кода, это тестовый вариант, потом будет приведен в порядок):
[code python]
#!/usr/bin/env python
import dns.resolver
from pprint import pprint
import random
import time
import asyncio
from datetime import datetime
DNS_RESOLVER = dns.resolver.Resolver()
name_server = ['192.168.5.254']
import platform
print(platform.python_version())
hosts = [
'microsoft.com',
'amazon.com',
'facebook.com',
'twitter.com',
'google.com',
'youtube.com',
'instagram.com',
'linkedin.com',
'wordpress.org',
'pinterest.com',
'wikipedia.org',
'wordpress.com',
'blogspot.com',
'apple.com',
'adobe.com',
'tumblr.com',
'youtu.be',
'amazon.com',
'goo.gl',
'vimeo.com',
'flickr.com',
'microsoft.com',
'yahoo.com',
'godaddy.com',
'qq.com',
'bit.ly',
'reddit.com',
'w3.org',
'baidu.com',
'nytimes.com',
't.co',
'europa.eu',
'buydomains.com',
'wp.com',
'statcounter.com',
'www.miitbeian.gov.cn',
'jimdo.com',
'blogger.com'
]
def random_delay():
return int(random.random() * 10)
format_len=max(hosts, key=len)
import async_timeout
async def resolve_dns(record, delay=0):
print(f"Run dns_query for host: {record:<20s} with delay: {delay}".format(record, delay))
try:
await asyncio.sleep(delay)
with async_timeout.timeout(10):
answer = DNS_RESOLVER.query(record, "A")
rcode = dns.rcode.to_text(answer.response.rcode())
print("HOST: {0:<20s}, rcode: {1}, delay: {2}".format(record, rcode, delay))
except Exception as e:
print("Host: {0:<20s} has resolving issue: {1}".format(record, e))
# raise
else:
pass
finally:
pass
def main():
print("Run main function")
DNS_RESOLVER.timeout = 3
DNS_RESOLVER.nameservers = name_server
pprint(vars(DNS_RESOLVER), indent=2)
start = time.time()
tasks = []
loop = asyncio.get_event_loop()
try:
tasks = [
loop.create_task(resolve_dns(host, random_delay()))
for host in hosts
]
loop.run_until_complete(asyncio.gather(*tasks))
finally:
loop.close()
end = time.time()
print("Total time: {}".format(end - start))
if __name__ == "__main__":
print(f"{__file__} executed")
main()
[/code]
В этом коде все работает хорошо, ровно до тех пор пока указан работающий DNS сервер, который не имеет проблем с ответами.
Как только указать не работающий, пропадает вся магия асинхронности и запросы к dns идут последовательно, при этом отваливаются по timeout
[code python]Run dns_query for host: buydomains.com with delay: 8
Run dns_query for host: wp.com with delay: 6
Run dns_query for host: statcounter.com with delay: 3
Run dns_query for host: www.miitbeian.gov.cn with delay: 6
Run dns_query for host: jimdo.com with delay: 5
Run dns_query for host: blogger.com with delay: 5
Host: wordpress.com has resolving issue: The DNS operation timed out after 30.002588987350464 seconds
Host: goo.gl has resolving issue: The DNS operation timed out after 30.00293493270874 seconds
Host: qq.com has resolving issue: The DNS operation timed out after 30.002574920654297 seconds
Host: bit.ly has resolving issue: The DNS operation timed out after 30.00347328186035 seconds
Host: reddit.com has resolving issue: The DNS operation timed out after 30.00317406654358 seconds
[/code]
Подскажите пожалуйста, как правильно переписать данный код для версии 3.6 чтобы timeout на какой-то из проверок не блокировал работу остальных потоков?
