2014-10-05 66 views
2

尋找一種方法來解決給定的完全限定的域名的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但它不是通常可用的,並且需要安裝額外的軟件包。

還有其他解決方案嗎?

回答

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 

吉爾無關用它作爲查找功能將在單獨的進程中執行,擁有自己的執行疊加。您可以在excellent python manpages上閱讀關於多處理選項的更多信息。

+0

恐怕不行了,因爲上面的函數直到完成才阻塞其他線程,所以不可能定期檢查它的狀態。試用CRuby和CPython的'socket.gethostbyname'。這是由於GIL在外部C庫調用期間阻止多個線程。 – 2014-10-05 21:04:40

+0

@DavidUnric我已經用一些細節和多處理示例更新了答案,如何實現你正在嘗試做的事情。 – 2014-10-05 21:22:35

+0

謝謝。你的例子確實有效,但是不是一個新線程,而是一個新的獨立進程。這是必需的,或者它會在線程中工作嗎?我很抱歉,我的主要語言是Ruby,不確定如何在Python中正確測試。 – 2014-10-05 21:35:30