ProxyAgent はすぐに接続できても、レスポンスボディを無期限に待つことがあります。プロキシエンドポイントの接続タイムアウトは、その後の待機を表しません。

エージェントを構築するときにエンドポイントへ接続の上限を設定します。下の公開 HTTP リクエストでは、公開中間業者が許される場合、HTTP プロキシ一覧の未認証の候補がアドレスを置き換えられます。

endpoint = TCP4ClientEndpoint(reactor, 'proxy.example', 8080,
                              timeout=5)
agent = ProxyAgent(endpoint, reactor=reactor)

メモリに集める小さなレスポンスでは、期限を追加する前にボディの読み取りを Deferred チェーンに含めます。

from twisted.web.client import readBody

d = agent.request(b'GET', b'http://example.com/')
d.addCallback(readBody)
d.addTimeout(10, reactor)
d.addCallback(lambda body: print(len(body)))
d.addErrback(lambda failure: print(failure.getErrorMessage()))

この断片は、アプリケーションがすでに reactor と設定済みのエージェントを持っていることを前提とします。ProxyAgent のリクエスト Deferred はレスポンスオブジェクトを返し、readBody はボディの Deferred を返します。コールバックからそれを返すと、チェーンはその処理も待ちます。

配置が重要です。Twisted は addTimeout を、その前に組み込まれたコールバックが表す処理に適用します。後からボディ読み取りを追加すると別の境界を表すことになります。この配置では、タイマーは addTimeout が呼ばれた時点で始まり、そのチェーンの保留中のリクエストとボディ処理をカバーします。

大きな、あるいは上限のないボディにはストリーミングのコンシューマを使い、完了を同じように表します。クライアント側の期限はアプリケーションが待つ時間を制限するものであり、プロキシ自身の上流接続タイムアウトを設定し直すものではありません。

関連記事