.NET remotingとdRuby
最近.NET Frameworkをいじり始めました。
.NETはVisualStudio .NETがなくても、無料の.NET Framework SDK(と適当なエディタ)だけで開発できるのな。不覚にも知らなかったです。とある事情で、まずは.NET remotingまわりを調査してます。
MSDNだとこのへんから辿れば必要な情報にたどり着けるでしょう。
.NET remoting概要
.NET remotingは、アプリケーション境界・マシン境界を超えた先にあるオブジェクトを透過的に使う仕組みです。C#で.NET remotingは、ちょっと試す分にはとても簡単です。
MarshalByRefObjectを継承したクラスを定義する
これでこのオブジェクトは、アプリケーションドメインを超えて参照渡しできるようになります。
(.NET CLRにはアプリケーションドメインとコンテキストって概念があるみたいだけどまだよく理解してない)
サーバ側とクライアント側に、XMLっぽい構成ファイルを置く
サーバ側は公開するオブジェクト名と公開するURL、クライアント側はアクセスするオブジェクトとそのURLを書きます。通信方法(tcpでバイナリデータ、httpでSOAP)やリモートオブジェクトの生成方法も指定できます(「アクティベーションの方法」という用語が使われてます)。
サーバ側は構成ファイルを読み込んで、ただ起動してればよい
構成ファイルを読み込むメソッドを呼び出して、ただwaitしていれば、リモートオブジェクトへの要求を受け付けるサーバのできあがり。
クライアント側は構成ファイルを読み込んで、リモートオブジェクトをnewする
newするだけでリモートオブジェクトが使えるようになるのだ。実際にリモートオブジェクトが生成されるのは、インスタンスメソッドが呼び出されたときのようです。
とまあこんな感じで、とっかかりは簡単です。
参照渡しと値渡し
さて、起動できるだけじゃだめで、リモートオブジェクトとクライアントの間ではなんらかの情報をやりとりしないといけません。それはメソッドの引数だったり戻り値だったりするわけです。
これらの値もアプリケーションドメイン境界を超えるわけですから、次のいずれかをしないといけません。
- MarshalByRefObjectを継承する
- serializableにしとく
1.であれば参照渡しになります。2.を行えば値渡しになります。どちらもやらないと、実行時例外になります。両方やると参照渡しになります(MarshalByRefObject自体はserializableになってます)。
とっかかりは簡単だったのに、この辺でもうめんどくさい感が漂ってきます。ぜんぜん透過的じゃないじゃん。リモートから使えるかどうか意識しなきゃだめじゃん。処理系がやってくれればいいじゃん。
まあこのくらいは、最小限のおまじないと思って我慢しないといけないのかな。もし構文上は完全にローカルなオブジェクトと同じように扱えても、リモートオブジェクトかどうかは結局意識しないといけない場面があるでしょうし。
インタフェース
次にひっかかるのが、サーバとなるリモートオブジェクトの型です。
これはクライアントとサーバのインタフェースですから、Interfaceで定義したくなっても不思議じゃありません。
ところがInterfaceで定義しても、クライアント側では具象型を指定しないとリモートオブジェクトを取り出せないみたいです。そのあとInterfaceにキャストして使ってもいいわけですが、そもそも取り出すときは型知らないとダメだってのがちょっといやです。
C#(とCLR)の仕様を考えれば仕方ないかな。
リモートオブジェクトをInterfaceで定義して、クライアント側ではオブジェクトの取り出しの時以外はInterfaceとして扱う、という実装はもちろんできますが。
dRubyだとどうなのさ
型がダイナミックなrubyでのリモート処理にはdRubyってのがあります。ちょっと調べてみたのですが、上記2点の問題については次のことがわかりました
値渡しと参照渡し
rubyそのものと同じく参照渡しのみ。どうしても値渡ししたかったら、オブジェクトをdupする(てかこれは値渡しじゃなくて、コピーの参照渡しですな)。実際に通信路にはどんなデータが乗ってるのかは未調査でよくわかりません。
インタフェース
そもそもrubyにはインタフェースがないです。というか型が動的です。サーバとなるリモートオブジェクトを使うクライアントにとって重要なのはその型ではなくて、送ったメッセージに反応できるかどうかってことだけ。
rubyなのでリモートの型とたとえば「リンク」しとく必要もなく、クライアント側をそのままでサーバ側オブジェクトをぜんぜん違う型にしちゃってもOK。同じメッセージに反応しさえすればいいのですな。