2014-10-05 2 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

Самый простой способ будет просто поставить запрос домена в потоке/процесса, а затем периодически проверять есть ли у нас данные обратно из него.

Edit: Как, как это сделать, вот простой пример в 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.

+0

Я боюсь, что, к сожалению, не будет работать, как выше функции блокировать другие темы, пока не закончено, так что это не возможно, чтобы периодически проверять его состояние. Пробовал с помощью CRuby и сокета «socket.gethostbyname» CPython. Это связано с тем, что GIL предотвращает несколько потоков во время вызова внешней библиотеки C. –

+0

@DavidUnric Я обновил ответ с некоторыми подробностями и примером многопроцессорности, как добиться того, что вы пытаетесь сделать. –

+0

Спасибо. Ваш пример работает, но вместо нового потока разворачивается новый отдельный процесс. Это необходимо или будет работать в потоке? Прошу прощения за то, что мой основной язык - Ruby и не уверен, как правильно тестировать Python. –

Смежные вопросы