4

ローカルで使用されるクラスを持つプログラムを作成していますが、同じクラスをネットワーク経由で同じ方法で使用したいと考えています。これは、パブリック メソッドのいずれかに対して同期呼び出しを行うことができる必要があることを意味します。このクラスはファイルを読み書きするので、XML-RPC はオーバーヘッドが大きすぎると思います。twisted の例を使って基本的な rpc クライアント/サーバーを作成しましたが、クライアントに問題があります。

c = ClientCreator(reactor, Greeter)
c.connectTCP(self.host, self.port).addCallback(request)
reactor.run()

これは 1 回の呼び出しで機能します。データが受信されたら、reactor.stop() を呼び出しますが、それ以上呼び出しを行うと、リアクターは再起動しません。これに使用する必要があるものは他にありますか?おそらく別のツイストモジュールまたは別のフレームワークですか?

(プロトコルがどのように機能するかの詳細は含めません。要点は、ここから 1 つの呼び出ししか得られないということです。)

補遺と説明:

私がやっていることについてのメモを含むGoogleドキュメントを共有しました。http://docs.google.com/Doc?id=ddv9rsfd_37ftshgpgz

ヒューズを使用し、複数のローカル フォルダーをヒューズ マウント ポイントに結合できるバージョンを作成しました。ファイル アクセスは既にクラス内で処理されているため、同じクラスへのネットワーク アクセスを提供するサーバーが必要です。検索を続けた後、私は pyro ( http://pyro.sourceforge.net/ ) が私が本当に探しているものかもしれないと思っています (単に彼らのホームページを今読んだことに基づいています) が、私はどんな提案も受け入れます.

nfs マウントを使用してローカル フォルダーと組み合わせることで同様の結果を得ることができますが、すべてのピアが同じ組み合わせファイルシステムにアクセスできるようにするため、すべてのコンピューターが多数の nfs を持つ nfs サーバーである必要があります。ネットワーク内のコンピューターの数と同じ数をマウントします。

結論: rpyc を使用することにしました。探していたものが正確に得られたからです。ローカルであるかのように操作できるクラスのインスタンスを保持するサーバー。誰かが興味を持っている場合は、私のプロジェクトを Launchpad ( http://launchpad.net/dstorage ) に掲載します。

4

4 に答える 4

2

Pyroを検討している場合でも、最初にRPyCを確認してから、XML-RPCを再検討してください。

ツイストについて:原子炉を停止するのではなく、そのままにしておくようにしてくださいClientCreator(...).connectTCP(...)

プロトコルを使用している場合はself.transport.loseConnection()、接続を開いたままにすることはありません。

于 2008-11-13T22:53:32.297 に答える
2

同期クライアントの場合、Twisted はおそらく適切なオプションではありません。代わりに、socket モジュールを直接使用したい場合があります。

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()文字列が得られるまで呼び出しを繰り返す必要があるかもしれませんが、これは基本を示しています。

または、プログラム全体を再配置して、非同期呼び出しをサポートすることもできます...

于 2008-11-11T20:04:35.330 に答える
2

なぜ同期する必要があると思いますか?

一度に 1 つのみが発生するようにしたい場合は、DeferredSemaphore を介してすべての呼び出しを呼び出して、実際の呼び出しを (任意の値に) レート制限できるようにします。

これらの複数のストリームを異なる時間に実行できるようにしたいが、同時実行制限を気にしない場合は、少なくともリアクターの起動とティアダウンを呼び出しから分離する必要があります (リアクターはプロセスの存続期間全体にわたって実行する必要があります)。 )。

アプリケーションのロジックをリアクター パターンで表現する方法がわからない場合は、deferToThread を使用して純粋な同期コードのチャンクを作成できますが、これは必要ないと思います。

于 2008-11-24T23:32:46.583 に答える
1

Twisted を使用している場合は、次のことを知っておく必要があります。

  1. どのネットワーク サービスに対しても同期呼び出しを行うことはありません
  2. リアクターは 1 回しか実行できないためreactor.stop()、アプリケーションを終了する準備ができるまで ( を呼び出して) 停止しないでください。

これがあなたの質問に答えることを願っています。個人的には、Twisted があなたのユース ケースにぴったりのソリューションであると信じていますが、シンクロニシティの問題を回避する必要があります。

補遺と説明:

私が理解していないことの一部は、reactor.run() を呼び出すと、ネットワーク アクティビティを監視するだけのループに入るように見えることです。ネットワークを使用している間、プログラムの残りの部分を実行し続けるにはどうすればよいですか? それを乗り越えることができれば、おそらくシンクロニシティの問題を解決できるでしょう。

それがまさに、reactor.run() が行うことです。イベント リアクタであるメイン ループを実行します。Entwork イベントを待機するだけでなく、発生するようにスケジュールされている他のすべてのイベントを待機します。Twisted では、アプリケーションの残りの部分を、その非同期性に対処する方法で構築する必要があります。おそらく、それがどのような種類のアプリケーションであるかを知っていれば、アドバイスできるでしょう.

于 2008-11-11T22:07:13.990 に答える