lendo um fluxo feita por urllib2 nunca se recupera quando a conexão foi interrompida

StackOverflow https://stackoverflow.com/questions/811446

  •  03-07-2019
  •  | 
  •  

Pergunta

Ao tentar fazer uma das minhas aplicações python um pouco mais robusto em caso de interrupções de conexão eu descobri que chamar a função de leitura de um http-stream feita por urllib2 pode bloquear o script para sempre.

Eu pensei que a função de leitura será tempo limite e, eventualmente, gerar uma exceção, mas isso não costura para ser o caso quando a ligação foi interrompida durante uma chamada de função de leitura.

Aqui está o código que fará com que o problema:

import urllib2

while True:
    try:
        stream = urllib2.urlopen('http://www.google.de/images/nav_logo4.png')
        while stream.read(): pass
        print "Done"
    except:
        print "Error"

(Se você experimentar o script, você provavelmente precisará interromper a ligação várias vezes antes de você chegar ao estado a partir do qual o script nunca se recupera)

Eu assisti o script via Winpdb e fez uma imagem do estado do qual o script nunca mais se recuperar (mesmo se a rede tem disponível novamente).

Winpdb http://img10.imageshack.us/img10/6716/urllib2.jpg

Existe uma maneira de criar um script python que vai continuar a trabalhar mesmo confiável, se a conexão de rede foi interrompida? (Eu preferiria evitar fazer isso dentro de uma linha extra.)

Foi útil?

Solução

Tente algo como:

import socket
socket.setdefaulttimeout(5.0)
   ...
try:
   ...
except socket.timeout:
   (it timed out, retry)

Outras dicas

Boa pergunta, eu estaria realmente interessado em encontrar uma resposta. A única solução que eu poderia pensar é usando o truque sinal explicado em python docs . No seu caso, será mais parecido com:

import signal
import urllib2

def read(url):
    stream = urllib2.urlopen(url)
    return stream.read()

def handler(signum, frame):
    raise IOError("The page is taking too long to read")

# Set the signal handler and a 5-second alarm
signal.signal(signal.SIGALRM, handler)
signal.alarm(5)

# This read() may hang indefinitely
try:
    output = read('http://www.google.de/images/nav_logo4.png')
except IOError:
    # try to read again or print an error
    pass

signal.alarm(0)          # Disable the alarm
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top