[python] Problém s blokujícím urlopen

David dunric29a na gmail.com
Pátek Březen 31 13:30:31 CEST 2017


Zdravím,

snad mi poradí někdo tady.

V jedné aplikaci stahuji soubor přes http pomocí urlopen z modulu
urllib2. Konkrétně se jedná o textový soubor s údaji o počasí, ale
problém se týká obecně jakéhokoliv uri.

Funkce urlopen přijímá v parametru timeout časový limit pro navázání
spojení, který ale zřejmě ignoruje když je nedostupná DNS.
Následující kód by měl skončit po cca 3 sekundách při neúspěšném
spojení, ale zasekne se a skončí asi až po minutě.

import urllib2
url = 'http://weather.noaa.gov/pub/data/observations/metar/stations/
LKPR.TXT'
try:
       data = urllib2.urlopen(url, timeout=3)
except:
       print 'Failed to retrieve a data !'

V případě navazování spojení na nameserver skript dokonce nereaguje
ani na signál SIGALRM.
Následující kód by měl vyvolat výjimku po 3 sekundách, ale také
zůstane viset na 20x delší dobu:

import urllib2, signal

def sig_handler(num,frame):
  raise Exception('Failed to retrieve a data !')

try:
   signal.signal(signal.SIGALRM, sig_handler)
   signal.alarm(3)
   data = urllib2.urlopen('http://weather.noaa.gov/pub/data/
observations/metar/stations/LKPR.TXT')
except Exception as excpt_dsc:
   print str(excpt_dsc)

Zkoušel jsem i nastavit socket.setdefaulttimeout, ale taky bez efektu.

Podmínkou je, že síťové rozhraní musí být nakonfigurované a aktivní,
ale nesmí být dostupný žádný z nakonfigurovaných DNS serverů. Tohle se
stává dost často u mobilních notebooků, než se nebo pokud vůbec podaří
překonfigurovat síť na novém místě. Aplikace po tu dobu vůbec
nereaguje.

Python 2.6.4, Linux 2.6.33, glibc 2.11.1

Předem díky za nakopnutí správným směrem.

David


Další informace o konferenci Python