7

私のpythonプログラムは、httplib2.Httpを使用してhttpリクエストを作成します。リクエストを生成する必要が生じたら、httplib2.Http オブジェクトを作成します。これにより、プログラムが httplib2.Http オブジェクトを頻繁に作成/破棄できるようになります。

開いているファイルの最大数に達したため、プログラムが簡単にクラッシュすることがわかりました。/proc//fd を確認すると、開いているソケット fd が多すぎます。この問題により、httplib2 ソース コードを掘り下げる必要が生じました。

次に、httplib2.Http._conn_request メソッドに、次のようなコードがあることがわかりました。

        else:
            content = ""
            if method == "HEAD":
                conn.close()
            else:
                content = response.read()
            response = Response(response)
            if method != "HEAD":
                content = _decompressContent(response, content)
        break

これは、http メソッドが HEAD の場合にのみソケットが閉じられることを示しています。おそらく、httplib2 はソケットを再利用したかったのでしょう。しかし、Http クラスには close() メソッドがありません。つまり、Http リクエストを行うと、プロセスが終了するまでソケットは閉じません。

次に、コードを変更しました:

        else:
            content = ""
            if method == "HEAD":
                conn.close()
            else:
                content = response.read()
            response = Response(response)
            if method != "HEAD":
                content = _decompressContent(response, content)
                conn.close() # I ADD THIS CLOSE
        break

その後、私のプログラムはうまくいきました。

しかし、httplib2 が非常に古くて一般的なライブラリであることを考えると、これが本当に httplib2 のバグなのかどうかはまだ興味があります。

4

1 に答える 1

7

いいえ、接続が閉じられていないという事実はバグではありません。次のリクエストで接続を再利用する必要があります。

方法httplib2は書かれており、サーバーが接続を閉じるか、タイムアウトするのを待ちます。積極的にそれらを閉じません(エラーを除く)。接続が閉じられている場合はhttplib2、次に使用するときに再確立を試みます。

接続を閉じると(ソースへのパッチのように)これが不可能になり、すべてのリクエストで独自の接続を使用する必要があります。

オブジェクトを破棄するhttplib2.Httpと、開いている接続はその辞書でのみ参照されるため、自動的に閉じられるはずです。そのため、作成したオブジェクトconnectionsへの参照を保持しない場合は機能するはずです。Httpぶらぶらしている参照がありませんか?

Connnection: closeまたは、リクエストにヘッダーを渡すこともできます。

http.request("http://example.org", headers={'Connection': 'close'})

これにより、サーバーは各リクエストの後に接続を閉じる必要があります。または、オブジェクトの辞書内のすべての接続を手動で閉じようとすることもできますconnections

于 2013-05-22T09:58:32.753 に答える