Обнаружение зависаний с помощью Python urllib2.urlopen - PullRequest
13 голосов
/ 06 апреля 2011

Я использую urllib2 в Python для отправки HTTP-сообщения:

import socket, urllib, urllib2

socket.setdefaulttimeout(15)    

postdata = urllib.urlencode({'value1' : 'a string', 'value2' : 'another string'})
headers = {
    'User-Agent': 'Agent',
    'Content-Type': 'application/x-www-form-urlencoded',
    'Accept': 'text/html, */*',
}

try: 
    request = urllib2.Request('http://www.example.com', postData, headers)
    response = urllib2.urlopen(request)
except urllib2.HTTPError, e:
    # Handle here
except urllib2.URLError, e:
    # Handle here
except httplib.HTTPException, e:
    # Handle here

Иногда проблема с сетью приводит к тому, что вызов urlopen никогда не возвращается. Мы видим, что другие ошибки (включая тайм-ауты) корректно обрабатываются блоком кроме, и у нас есть вызов socket.setdefaulttimeout (), но все еще есть случаи, когда urlopen никогда не вернется.

Я знаю, что он никогда не возвращается, потому что у нас есть некоторые строки журнала в нашем фактическом коде, которые вызываются до и после, и когда возникает эта проблема, выполняются только вызовы до того, как сценарий зависает навсегда.

Какой лучший способ обнаружить / обработать это?

1 Ответ

10 голосов
/ 06 апреля 2011

Вы можете использовать сигналы, сначала установите обработчик для своего сигнала

import signal
...
def handler(signum, frame):
    print 'Signal handler called with signal', signum
...
signal.signal(signal.SIGALRM, handler)

и поставьте будильник непосредственно перед urlopen вызовом

signal.alarm(5)
response = urllib2.urlopen(request)
signal.alarm(0) # Disable the signal

после 5секунд (или желаемое время) ОС вызовет обработчик, если будильник не отключен (если urlopen никогда не возвращается).Больше информации о сигнальном модуле: http://docs.python.org/library/signal.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...