2012-04-24 4 views
1

次のシナリオを検討してください。サーバー上のプロセスは、ネットワーク接続からのデータを処理するために使用されます。 Twistedを使用すると、spawnProcessで非常に簡単になり、ネットワーク側のプロトコルにProcessTransportを簡単に接続できます。ツイストアプリケーションでのメモリ境界

しかし、ネットワークからのデータが標準入力で読み取る処理よりも速く処理できる状況をTwistedがどのように処理するのか判断できませんでした。私が見る限り、Twistedコードは、消費されていないデータを格納するために内部バッファ(self._bufferなど)を使用しています。これは、高速接続(例えば、ローカルギガビットLAN経由)からの同時要求がメインメモリをいっぱいにし、重いスワップを引き起こし、状況をさらに悪化させる可能性があるのではないでしょうか?どのようにこれを防ぐことができますか?

理想的には、内部バッファには上限があります。私が理解しているように、OSのネットワーキングコードは、OSのバッファがいっぱいになると自動的に接続を停止し、パケットを破棄し始めます。これはクライアントの速度を落とします。 (はい、私は知っている、ネットワークレベルのDoSはまだ可能ですが、これは別の問題です)。これは、自分で実装する場合のアプローチでもあります。内部バッファがいっぱいであれば、ソケットから読み取らないでください。

サービスが任意のサイズのファイルを処理できる必要があるため、最大リクエストサイズを制限することも私の場合は選択できません。

答えて

5

溶液には2つの部分があります。

の部分は、と呼ばれます。プロデューサは、データが出てくるオブジェクトです。 TCPトランスポートはプロデューサです。プロデューサーには便利な方法がいくつかあります:pauseProducingresumeProducingです。 pauseProducingは、トランスポートにネットワークからのデータの読み取りを停止させます。 resumeProducingが読み込みを再開します。これにより、まだ処理していないメモリに無制限の量のデータが蓄積されないようにすることができます。あなたが後ろに降り始めると、輸送を一時停止するだけです。あなたが追いついたら、それを再開してください。

他の部分は、コンシューマと呼ばれます。消費者は、データが入るオブジェクトです。 TCP転送も消費者です。あなたの場合より重要なのは、子プロセス輸送も消費者であることです。消費者にはいくつかの方法がありますが、特にあなたには便利です:registerProducer。これは、どのプロデューサデータがそこから来ているかを消費者に知らせる。消費者はデータ処理能力に応じてpauseProducingresumeProducingと呼ぶことができます。トランスポート(TCPまたはプロセス)がデータを送信するようにプロデューサが要求するほど高速にデータを送信できない場合、プロデューサは一時停止します。それが追いつくと、再びそれを再開します。

read more about producers and consumers in the Twisted documentationです。