RPCのバージョン

3
Sadayuki Furuhashi @frsyuki

MessagePack-RPC Java版は、EventLoopがイベントループと見せかけて実はスレッドプールという実装。スレッドはI/Oスレッドとworkerスレッドに分かれる。

2010-12-24 08:38:04
Sadayuki Furuhashi @frsyuki

workerスレッドは、dispatch以下でSEDA的に多段にしていけると良さそう。そこでスレッドプールのインタフェースを取り決める案。イベントループはI/Oスレッドだけを持ち、workerスレッドにはスレッドプールをattachする形を取る設計。

2010-12-24 08:42:12
Sadayuki Furuhashi @frsyuki

dispatcherの実装は、メッセージのルーティング方法を実装する形ではなく、メッセージを処理する方がルータにマッチ条件とコールバック関数、それからメッセージの型変換テンプレートを登録する形でも良さそうかな、と思っているところ。コードを書くときにはこちらの方が嬉しい。

2010-12-24 08:52:38
Sadayuki Furuhashi @frsyuki

register(string method, template<T> template, function<void (T)> callback) という感じ。ただコードを読むときは、メソッドの一覧性が悪くなるのが困る。あと静的に決まらない。

2010-12-24 08:55:49
Sadayuki Furuhashi @frsyuki

折衷案として、最近作っているシステムではdispatcher側に slot を宣言しておき、メッセージを処理する方が slot にコールバック関数を connect するという、QTのやり方を拝借してみた。これは悪くなかったので、この案でも良さそう。

2010-12-24 08:59:37
Sadayuki Furuhashi @frsyuki

このslot-connectの仕組みとスレッドプールは統合できそうだという話で、この辺りを一般化してライブラリにしたい。C++だとメモリ管理が若干面倒か…。

2010-12-24 09:04:18
Sadayuki Furuhashi @frsyuki

スレッドプールは0mq的な機能の布石にもなり得て、メッセージの出口と入口をプラガブルにすると色々できる。slot-connectは出口の1実装として設計すると良いのかも。

2010-12-24 09:09:00
Sadayuki Furuhashi @frsyuki

いけてるスレッドプールを標準で持っているJavaは便利すぎるというか、java.util.concurrentはヒキョーである。

2010-12-24 09:10:21
Sadayuki Furuhashi @frsyuki

RPCのバージョン。たぶんバージョンを付ける方法は2種類あって、1つはプロトコルのセット全体にバージョンを付ける方法、もう1つはメソッドごとにバージョンを付ける方法。

2010-12-24 09:15:13
Sadayuki Furuhashi @frsyuki

たぶん発生する要求は、古いメソッドもサポートしたまま(場合によっては同名の)新しいメソッドを追加して、段階的に古いメソッドを無くしていきたいケース。それから既にサポートしていない古いメソッドが呼ばれたら、それはバージョンが古いクライアントだよ、とメッセージを表示したい。

2010-12-24 09:18:05
Sadayuki Furuhashi @frsyuki

プロトコル的には、メソッド名にバージョン番号を付けるのが良さそうだと思っているところ。set:0(key,value), set:1(key,value,flag) という感じ。実際のプログラムでは、オーバーロードされたsetメソッドが呼ばれる。

2010-12-24 09:20:17
Sadayuki Furuhashi @frsyuki

コロンの後ろはバージョン番号であるというのをライブラリ側で理解しているのはポイントで、例えばバージョン番号の付いていないsetが呼ばれたら、自動的にset:0を呼ぶ。set:0には対応する実装がconnectされていないのにset:0が呼ばれたら、それはもう古いと返すとか。

2010-12-24 09:23:14
Sadayuki Furuhashi @frsyuki

後ろのバージョン番号は「メジャーバージョン」で、flagの追加くらいはoptionalで対応できるハズ。でもこの辺りの高級な処理をサポートしようと思うと、リフレクションかIDLは必須になりそう。C++は厳しいな…。

2010-12-24 09:25:21
Sadayuki Furuhashi @frsyuki

バージョン番号を「プロファイル名」に拡張すると、プロトコルの標準化に使えそう。USBのclassやbluetoothのprofileに相当する話。下位のMessgePack-RPCの上に、上位のプロトコル仕様を定める。

2010-12-24 09:28:40
Sadayuki Furuhashi @frsyuki

set:kvs-profileという感じ。実際のサーバ側の実装は、 set:kvs-profile(key, value) { myset(key, value, 0.0, 0); } という感じで、シンプルなアダプタになるハズ。これをサポートしているとクライアント側が嬉しい。

2010-12-24 09:30:04
Sadayuki Furuhashi @frsyuki

MessagePack-RPC kvs-profileをサポートしているサーバなら何でも使える、という感じ。でもどうやって標準化するのかという問題があるので、たぶんそんなにうまくいかない。最初はアプリケーション名くらいになるのかも。

2010-12-24 09:33:31
Nobuyuki Kubota @nobu_k

まあいきなり最適解を知っても面白くないし、今のメンツ・状況なら失敗しても笑って乗り越えられるので、みんなで失敗しながら改善していく感じでも良いかと思ってるけど。

2010-12-27 00:08:54
Nobuyuki Kubota @nobu_k

怖いのは失敗を恐れるあまり保守的になりすぎることかな。研究からすごいものが出てきてもそれを受け入れるだけの余裕が開発側になかったら悲しい。もちろんある程度保守的にならなければいけないけれど、たまに激しく暴走してみても、それを余裕で吸収できちゃうくらいの体制は作りたいなあ。

2010-12-27 00:11:24
Nobuyuki Kubota @nobu_k

やっぱり冒険すると、「やべwwwwww、失敗すると死ぬwwwwwwww」みたいな感じになって楽しいので、定期的にそういう感覚がほしいところ。

2010-12-27 00:13:56
Nobuyuki Kubota @nobu_k

妄想していたやつがMessagePack-RPCの上にのっけられそうな気がしてきた。MessagePackを2段挟む感じになるけど問題ないはず。ライブラリの層で完全に吸収できる。

2010-12-27 01:20:32
Nobuyuki Kubota @nobu_k

結局関数単位で互換性が維持されてもあまり嬉しくないんだよね。もう少し大きな範囲でバージョンを明確に区別したい。そんで管理も簡単にしたい。

2010-12-27 01:25:46
Sadayuki Furuhashi @frsyuki

@nobu_k もう少し大きな範囲というと…機能Aに属する関数1と関数2があるときに、関数1と関数2をセットでバージョン管理したい(互換・非互換の切れ目を管理したい)という感じですか?

2010-12-27 01:30:59
Sadayuki Furuhashi @frsyuki

一連の関数群があって、クライアントはRPCで次々に呼び出していくけど、過去の関数と新種の関数が混じって呼ばれるとマズイケースはありそう(コレは互換性維持のためだけにある機能です、混ぜるな危険、的な関数が呼ばれているとか)。

2010-12-27 01:40:46
Sadayuki Furuhashi @frsyuki

基本のMessagePack-RPCはシンプルに抑えたいけど、その上に拡張仕様を乗せたいことはありそう。全部MessagePack-RPCでサポートするのは厳しいから、独自で拡張しやすくする仕組みを入れると良さそうか。

2010-12-27 01:45:49