非阻塞主机名解析?

时间:2014-10-05 18:57:19

标签: python ruby dns

寻找如何解决给定完全限定域名的IPv4 / IPv6地址的方法,但是在有限的时间内。

我已经尝试了几种使用标准Ruby库的方法,但是所有这些方法都阻塞了其他线程,因此超时异常无法生效:

Timeout.timeout(1) {addr = Socket.sockaddr_in 80,'google.com'}
Timeout.timeout(1) {addr = Socket.getaddrinfo 'google.com','http',nil,:STREAM}
Timeout.timeout(1) {addr = Socket.gethostbyname 'google.com'}

当DNS响应缓慢或暂时无法访问时,上述所有尝试都不会在60秒内停止,而不是1秒钟。

我知道adns但它通常不可用,需要安装额外的软件包。

还有其他解决方案吗?

1 个答案:

答案 0 :(得分:2)

最简单的方法是将域查询放在线程/进程中,然后定期检查我们是否从中获取了信息。

编辑: 至于如何做,这是python中的一个简单示例:

from multiprocessing import Pool
import socket
import time

def lookup(host):
    return socket.gethostbyname(host)

if __name__ == "__main__":
    pool = Pool(processes=4)
    result = pool.apply_async(lookup, ("google.com",))
    done = 0
    while done < 60: # Here we do something weird while domain lookups work in background
        print(done)
        done += 1
        time.sleep(1)

    # Now we need the domain details so we get em
    print(result.get(1)) # 1 second timeout since it already had 60 seconds to process

Gil与它无关,因为查找函数将在具有自己的执行堆栈的单独进程中执行。您可以在excellent python manpages上阅读有关多处理选项的更多信息。