接続が中断されたときにurllib2によって作成されたストリームを読み取ると回復しない
質問
接続が中断された場合にPythonアプリケーションの1つをもう少し堅牢にしようとすると、urllib2によって作成されたhttp-streamの読み取り機能を呼び出すと、スクリプトが永久にブロックされることがあります。
読み取り関数はタイムアウトし、最終的に例外が発生すると考えましたが、読み取り関数の呼び出し中に接続が中断された場合はそうなりません。
問題を引き起こすコードは次のとおりです。
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"
(スクリプトを試してみると、スクリプトが回復しない状態に達する前に、おそらく接続を数回中断する必要があります)
Winpdbを介してスクリプトを監視し、(ネットワークが再び利用可能になったとしても)スクリプトが回復しない状態のスクリーンショットを作成しました。
Winpdb http://img10.imageshack.us/img10/6716/urllib2.jpg
ネットワーク接続が中断された場合でも信頼性の高い動作を続けるPythonスクリプトを作成する方法はありますか? (余分なスレッド内でこれを行うことは避けたいです。)
解決
次のようなものを試してください:
import socket
socket.setdefaulttimeout(5.0)
...
try:
...
except socket.timeout:
(it timed out, retry)
他のヒント
良い質問です。答えを見つけることに本当に興味があります。私が考えることができる唯一の回避策は、 pythonドキュメントで説明されているシグナルトリックを使用することです。 。 あなたの場合、次のようになります:
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
所属していません StackOverflow