質問
ローカルで使用されるクラスを持つプログラムを構築していますが、ネットワーク上で同じクラスを同じ方法で使用したいです。これは、そのパブリックメソッドのいずれかを同期呼び出しできる必要があることを意味します。このクラスはファイルを読み書きするため、XML-RPCはオーバーヘッドが大きすぎると思います。ツイストの例を使用して基本的なrpcクライアント/サーバーを作成しましたが、クライアントに問題があります。
c = ClientCreator(reactor, Greeter)
c.connectTCP(self.host, self.port).addCallback(request)
reactor.run()
これは、単一の呼び出しで機能します。データが受信されると、reactor.stop()を呼び出していますが、それ以上呼び出しを行うと、reactorは再起動しません。これに使用する必要がある他のものはありますか?別のツイストモジュールまたは別のフレームワークですか?
(プロトコルの仕組みの詳細は含めません。主な点は、この呼び出しから1回だけ呼び出しを行うことです。)
補遺&明確化:
Googleドキュメントを共有し、自分がやっていることに関するメモを共有しました。 http://docs.google.com/Doc?id=ddv9rsfd_37ftshgpgz
ヒューズを使用し、複数のローカルフォルダーをヒューズマウントポイントに結合できるバージョンがあります。ファイルアクセスは既にクラス内で処理されているため、同じクラスへのネットワークアクセスを許可するサーバーが必要です。検索を続けた後、pyro( http://pyro.sourceforge.net/ )が何であるかを疑います私は本当に探しています(単に彼らのホームページを今読んでいることに基づいています)が、私はどんな提案にも寛大です。
nfsマウントを使用してローカルフォルダーと結合することで同様の結果を得ることができましたが、すべてのピアが同じ結合ファイルシステムにアクセスできるようにするため、すべてのコンピューターがnfsサーバーである必要がありますネットワーク内のコンピューターの数に等しいnfsマウントの数。
結論: 私が探していたものを正確に提供してくれたrpycを使用することにしました。ローカルのように操作できるクラスのインスタンスを保持するサーバー。誰かが興味を持っている場合は、Launchpadにプロジェクトを置きます( http://launchpad.net/dstorage )。
解決
Pyroを検討している場合は、まず RPyC を確認し、XML-RPCを再検討してください。 。
Twistedについて:リアクターを停止するのではなく、そのままにしておき、毎回 ClientCreator(...)。connectTCP(...)
を実行してください。
プロトコルで self.transport.loseConnection()
を使用すると、接続を開いたままにすることはできません。
他のヒント
なぜ同期する必要があると思うのですか?
一度にこれらの1つだけが発生するようにしたい場合は、DeferredSemaphoreを介してすべての呼び出しを呼び出して、実際の呼び出しを(任意の値に)レート制限できるようにします。
これらの複数のストリームを異なる時間に実行できるようにしたいが、同時実行の制限を気にしない場合は、少なくともリアクターの起動とティアダウンを呼び出しから分離する必要があります(リアクターはライフタイム全体で実行する必要がありますプロセスの)。
リアクターパターンでアプリケーションのロジックを表現する方法がわからない場合は、deferToThreadを使用して、純粋に同期的なコードの塊を書くことができます-これは必要ないと思いますが
同期クライアントの場合、おそらくTwistedは適切なオプションではありません。代わりに、ソケットモジュールを直接使用することもできます。
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((self.host, self.port))
s.send(output)
data = s.recv(size)
s.close()
recv()
呼び出しは、空の文字列を取得するまで繰り返す必要がありますが、これは基本を示しています。
また、プログラム全体を再配置して非同期呼び出しをサポートすることもできます...
Twistedを使用している場合は、おそらく次のことを知っている必要があります。
- ネットワークサービスへの同期呼び出しは行いません
- リアクターは一度しか実行できないため、アプリケーションを終了する準備ができるまで、(
reactor.stop()
を呼び出して)リアクターを停止しないでください。
これがあなたの質問に答えることを願っています。個人的には、Twistedはユースケースに対して正確に正しいソリューションであると考えていますが、同期の問題を回避する必要があると考えています。
補遺&明確化:
私が理解できないことの一部は reactor.run()を呼び出すと ループに入るようです ネットワークアクティビティを監視します。どうすればいい 私の残りを実行し続けます ネットワークを使用しながらプログラム?もし それを乗り越えることができます おそらく動作します 同期性の問題。
これはまさに、reactor.run()が行うことです。イベントリアクターであるメインループを実行します。 entworkイベントだけでなく、発生するようにスケジュールした他のイベントも待機します。 Twistedでは、アプリケーションの残りの部分を非同期の性質に対処するように構造化する必要があります。おそらく、それがどのようなアプリケーションであるかを知っていれば、アドバイスできます。