1

URL に接続して json を取得する API マネージャーがあります。とてもシンプルです。メソッドから切り取ります:

req = Request(url)
socket.setdefaulttimeout(timeout)
resp = urlopen(req, None, timeout)
data = resp.read()
resp.close()

ほとんどの場合は問題なく動作しますが、ランダムな間隔でリクエストを完了するのに 5 秒かかります。タイムアウトが 0.5 または 1.0 などに設定されている場合でも。私はそれを非常に綿密に記録したので、時間がかかる行が 3 番であると 100% 確信しています (つまり、resp = urlopen(req, None, timeout))。

タイムアウトデコレータやタイマーなどのトピックで見つけたすべての解決策を 試し ましPython 2.4での動作、終了まで時間がかかりすぎる場合のタイムアウト機能 )

しかし、何も機能しません。私の印象では、urlopen が何かを実行している間にスレッドがフリーズし、完了するとフリーズが解除され、すべてのタイマーとタイムアウトが w タイムアウト エラーを返します。しかし、実行時間はまだ5秒以上です。

urllib2 とチャンク エンコーディングの処理に関するこの古いメーリング リストを見つけました。したがって、問題が解決しない場合は、httplib.HTTPConnection ではなく、httplib.HTTP に基づいてカスタム urlopen を作成することで解決できる可能性があります。別の可能な解決策は、マルチスレッドの魔法を試すことです....

どちらの解決策も攻撃的なようです。そして、タイムアウトが完全に機能しないことが私を悩ませています。

スクリプトの実行時間が 0.5 秒を超えないようにすることが非常に重要です。フリーズが発生している理由を知っている人、または私を助ける方法を知っている人はいますか?

受け入れられた回答に基づく更新: アプローチを変更し、代わりにcurlを使用しました。一緒に w unix タイムアウトは、私が望むように機能します。コード例は次のとおりです。

t_timeout = str(API_TIMEOUT_TIME)
c_timeout = str(CURL_TIMEOUT_TIME)
cmd = ['timeout', t_timeout, 'curl', '--max-time', c_timeout, url]
prc = Popen(cmd, stdout=PIPE, stderr=PIPE)
response = prc.communicate()

curl はタイムアウトとして int のみを受け入れるため、タイムアウトを追加しました。timeout は float を受け入れます。

4

1 に答える 1