MessagePack, BufferPacker, StreamPacker の設計について

2
Sadayuki Furuhashi @frsyuki

BufferPackerとStreamPackerを分けるのは微妙で、たぶんそもそもStreamPackerで、あと BufferPacker extends Packer にするのが良いのではないかという案が1点と

2011-07-22 13:16:31
Sadayuki Furuhashi @frsyuki

あと JSON extends MessagePack が厳しくて(createBufferUnpacker)、現状のBufferUnpackerのインタフェースは全機能を実装するのが難しい。特にfeed。状態遷移マシンベースのデシリアライザが必須。

2011-07-22 13:18:57
Sadayuki Furuhashi @frsyuki

気合い入れてRagelで書くとか、そういう手段をあとで取るとして、現状は JSON extends MessagePack にして JSON では feed は UnsupportedOperationException を投げる案か、

2011-07-22 13:20:18
Sadayuki Furuhashi @frsyuki

createBufferUnapckerメソッドなど実装が難しいAPIを含まない基底interfaceを作って、MessagePack implements ソレ + JSON implements ソレ にするか(JSONではByteArrayOutputStreamを使う)

2011-07-22 13:21:41
Sadayuki Furuhashi @frsyuki

たぶん、後者のが良さそうな印象。それと関連してTemplateRegistryを誰が所有するか問題で…ありそうなケースは、JSONとMessagePackの両方を入力データとしてサポートしくて、@Messageクラスも同じという場合。TemplateRegistryを共有したい。

2011-07-22 13:23:31
Sadayuki Furuhashi @frsyuki

一つの案は、TempalteRegistry tr = new TemplateRegistry(); MessagePack m = tr.createMessagePack(); とか。ちょぃと長い。使い勝手的に微妙感。綺麗だけど。

2011-07-22 13:24:58
Sadayuki Furuhashi @frsyuki

そういう使い方をする人はadvancedな人なので、コンストラクタ MessagePack(TemplateRegistry); を用意しつつ、デフォルトでは MessagePack() { this(new TemplateRegistry(); } を呼んでね♪という案も。

2011-07-22 13:28:18
Sadayuki Furuhashi @frsyuki

あるいは JSON(MessagePack m) { registry = m.registry; } とする案も。

2011-07-22 13:30:53
Sadayuki Furuhashi @frsyuki

1クラス1機能主義に反した大クラスが出現すると、こういう問題が出てくるのかなー。register() が表に見えている時点で、TemplateRegistry 的な存在というか概念は理解してもらえるハズで、それを共有するにはこうするーという方法が明確なら何でも良いと思うのだけども

2011-07-22 13:34:03
Sadayuki Furuhashi @frsyuki

JSONのデシリアライザは、unpackArrayBegin()が配列のサイズを返すことを要求する関係で、JSONUnpacker extends Converter になるはず。uArrayBegin()の方を変えるという案もあるけど、そこまでJSONに対応してもなぁと。

2011-07-22 13:36:25
Sadayuki Furuhashi @frsyuki

最初の話は、StreamPacker/BufferPacker の分け方については、たぶん BufferPacker は StreamPacker+ByteArrayOutputStream の最適化版なので、BufferPacker extends StreamPacker

2011-07-22 13:39:09
Sadayuki Furuhashi @frsyuki

が良くて、それなら名前は StreamPacker → Packer で良いと。関連して、Packer#close() を追加することになるハズ。BufferPacker#close() は何もしない。BufferPackerはPackerのAPIに加えて拡張APIを色々実装と。

2011-07-22 13:40:32
Sadayuki Furuhashi @frsyuki

Unpacker側も同じ。BufferUnpacker#close() は何もしない。UnpackerのAPIに加えてwrapとfeedを持つと。JSONでfeedの実装が厳しい件はUnsupportedOperationExceptionを投げるのが良さそうな気がしてきたー

2011-07-22 13:42:15
Sadayuki Furuhashi @frsyuki

Optional/NullableはOptionalに統一で…これはIDLも同じにする予定。optional修飾子が無くなって、?に統一かな。1: string? hoge とか。Templateをユーザーが直接使うことは無いと仮定すると、OptionalTemplateは不要。

2011-07-22 13:44:48
Sadayuki Furuhashi @frsyuki

代わりにunpack(…, bool allownull)で。が、前バージョンの Templates.tMap みたいなのを追加するとなると、OptionalTemplateも欲しくなる。実は案外にコレが欲しい。genericsの型情報がローカル変数から取れればなぁ。

2011-07-22 13:46:30
Sadayuki Furuhashi @frsyuki

これは後のバージョンで追加するか考える方針かな。

2011-07-22 13:48:38
Sadayuki Furuhashi @frsyuki

あとTemplateBuilderで、フィールドに対するデフォルトの挙動をどうするか。publicフィールドだけシリアライズ対象というのは良い妥協点だと思っていて、自分で使っていて普通に便利。が、privateなのもシリアライズしたいのは非常に分かる。

2011-07-22 13:51:12
Sadayuki Furuhashi @frsyuki

一つ考えている案は、register(Type) と registerBeans(Type) を作る案。JavaBeansに従ってもらう丸投げ。アノテーションも対応して @Message@BeansMessage という感じ。

2011-07-22 13:52:59
Sadayuki Furuhashi @frsyuki

デフォルトpublicフィールだけな方法と、JavaBeansで、どっちをデフォルトにするかは微妙。

2011-07-22 13:54:41
Taro L. Saito @taroleo

@frsyuki Scalaもまたフィールドが違うので両方で使えるといいですね。

2011-07-22 13:55:44
Sadayuki Furuhashi @frsyuki

あとはprivateなフィールドがあって、setterもgetterも無いクラスをシリアライズしたいというケースがあるハズ。これは register(Type, String[] fieldList) でどうでしょ?

2011-07-22 13:56:40
Sadayuki Furuhashi @frsyuki

optionalの指定もしたい場合もあるので、最終的に register(Type, FiedEntry[] fieldList) に落ちる形でオーバーロードを色々。メソッド名要検討…

2011-07-22 13:57:39
Sadayuki Furuhashi @frsyuki

yes! それもあるのです。RT @taroleo: @frsyuki Scalaもまたフィールドが違うので両方で使えるといいですね。

2011-07-22 13:57:47
bickey81 @bickey81

「MessagePack使ったらTPS300%アップした」というキャッチフレーズは社内の人にもインパクトあったみたいだ。

2011-07-22 13:59:44
Sadayuki Furuhashi @frsyuki

実はJRubyもあるという話は後にして、Scalaのフィールド一覧をFieldEntry[] に落とせれば何とかなりそうな予感。registerScalaClass とか…。これは 0.7.0 でも良い気がしてきました!

2011-07-22 14:01:04