Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
MessagePackが文字列とバイナリをわけないのは問題?

MessagePackが文字列とバイナリをわけないのは問題?

https://github.com/msgpack/msgpack/issues/121

Objective Cの実装使ってるとある問題にぶちあたった.なので,文字列をちゃんとバイナリ(Raw)と分けるべき,という提案

(*) 俺は熟読したわけではないので,中身が気になる人はちゃんと本スレを読みましょう

そもそもMessagePackとは

MessagePackはバイナリ形式のデータコンテナで,いくつかのプリミティブタイプとデータ構造(Map, List, Raw)を提供する.これがMessagePackの型であり,プログラミング言語は各それぞれの型にマッピングする.ここで重要なのは,MapやListやRawは構造を決めるだけで,中の型が何かまでは関知しない.それは上位レイヤーでハンドルするべき,という方針. これはwire formatとしては十分で,実際MessagePack RPC以外でも色々なところでMessagePackは内部フォーマットとして使われている.

MessagePackの抱える問題

MessagePackのMapは,キーになんでも入るが,言語によってはこれが出来ないのがある.なので,MessagePackの目的である多言語間での交換はだいたいにおいて上手くいくが,そうじゃないこともある. が,まぁそんなケースに向かない言語を実プロダクションで使うことはまずないので,アプリケーション間での約束毎(IDLなど)で基本問題が起きていない.

文字列?

文字列とバイナリは実は中のデータ構造は一緒で,それをどう見るかというviewが違う.なので,中ではバイナリで持っていて,RPCやより上位のレイヤーで適切にハンドリングするのが今のMessagePackでの使われ方. が,これが面倒なのでそれをMessagePackに入れろ,というのが多分今回の案(ドキュメントにちゃんと書け,と言っている人もいる).

欲しい人たちの意見

  • 文字列(UTF-8)は基礎的な型なので入れるべき
    • この人達は多分JSONな人たちでこれが欲しいだけなので,これが入れば多分納得する(エラーハンドリング周りはこの人たち考えてないようなので,その辺はこっちで詰める必要がある)
  • 言語によっては問題が起きるので,入れた方がベター
  • 実装者や利用者がちゃんとハンドルできるようにドキュメントが必要

It's like JSON

これに突っかかる人もいる.like JSONのように書いてるんだからJSONのreplacementとして動け!という感じだと思われる.

これはデータコンテナのフォーマットとしてはlike JSONは真で,置き換えという意味では少し違う.

実はJSON単体を扱うのであれば,MessagePackは上手く動く.実装が,バイナリを文字列として扱うオプションを指定すれば良い(utf-8でデコードするとか).また,簡単なヘルパー関数を書くだけでも良い. JSONはMessagePackの型制限版と考えれば,これで上手く行く.JSONはバイナリを持てないため,これで問題ない.

ただ,JSONと違いバイナリを持てるため,バイナリと文字列を含めるようになると,この方法は上手くいかない.実際これはアプリケーションやIDLなどのスキーマのレイヤーで吸収出来るものであるので,実際はそんなに大きな問題になっていない(BinaryPackの人も95%は上手くいくと書いている).

問題点はどこか?

これは静的型付けでは問題にはならない(多分).実際D言語などの静的型付けの言語では,利用する時に型が必要になり,これが一種のスキーマになる.そのため,MessagePackではバイナリであっても,ちゃんとアプリケーションレイヤーでは文字列など適切な型になっている.

問題は動的型付けな言語で,JSONの代わりに使っている人である.この人たちは,テキストフォーマットの代わりにデータコンテナであるMessagePackを使おうとしており,JSONのように復元時に文字列ままとして返して欲しいという要望.

そもそもユースケースが微妙に違うし一蹴してもいいのだけど,まぁ実際JSONの代わりにMessagePackは便利だし,ユースケースとして広まってきているので,そこが悩ましい.またこれを出来るようにしたMessagePackベースだけど互換性のないBinaryPackというのをIETFに提案しようとしているので,それがさらに面倒くさいという感じ.

意識のずれ

アプリケーションレイヤーでやるべきかフォーマットでサポートするべきかというところで,MessagePackユーザとそうでない人でずれがあり,ここが実は多分埋まってない.

解決策

  • ドキュメントの問題だ,と言っている人もいるので,これは多分やるべき(が,何を書くかという議論がまた必要
  • 文字列型を追加するか否か <= 今多分この辺
    • あったら便利である.いわゆるJSONな人たちを取り込むか否か,または動的型付けのレアケースに対応するか否か
    • 追加する場合はどういうフォーマットで,どうやって互換性を維持するかが問題 <= 今多分この辺
    • また,どういう風にvalidationするかなども多分必要
    • 各実装がどこまでそれに追従できるのかというのも大事

IETFの標準化について

今話の中心になっているこれに関して少し追記しておきます.BinaryPackそのものは,MessagePackに文字列(utf-8 string)がなかったから出来たフォーマットなんですが,これの標準化を急いでいるのは,他のプロジェクト(Smart Object? CoAP?周り)で必要だからだそうです(github issueコメント参照).

で,MessagePackコミュニティとしては,すでにissue 121の結果文字列をフォーマットに追加しようとしており,ここでの議論&実践が収束する前に,同じ文字列を異なるフォーマットを採用したforkが標準化されるのは,ちょっと困るという感じです(今厄介になっているのは,素のBinaryPackはもう提案されてなくて,今議論中のフォーマットをBinaryPack updateとしてそのまま提案している所).

ある程度実装が追従して,コミュニティとして新しいフォーマットが広まった段階であれば,おそらく反対はかなり少ないんじゃないかと思います.実際問題,俺を含め他の人の反応を見てると,IETFによる標準化そのものに反対している人はいない気がしています(大抵されて損はないですし,ugorjiさんもcabo-sanに,IETFでの標準化を助けようとしてくれていることに感謝している,みたいなことを書いている).

で,ただこれに関しては標準化に関する理解が皆まちまちなので,影響がどこまであるのかというのがよく分かってない情況.今まで出たおおまかな意見

  • MessagePack本家が標準化されるわけではないので放っておけばいいのでは?
    • 将来的にMessagePack本家が標準化する時にコンフリクトしそう?そもそもするのかという問題
    • その前にデファクトにならずに消える可能性もあるらしい
      • 広まった場合の微妙に互換性が無い問題はかなり面倒くさい
      • cabo-sanのユースケース的にこの可能性は高そうだが,running codeがあれば生き残る?
    • 標準化の効力がいまいち分かってないので,この辺実際どうなのかというのが疑問点
  • MessagePack本家もドラフトを出す
    • これでBinaryPackを止められるかもしれないが,上記の通り別に標準化そのものに反対はしてないので,今同じ時期に出すのはフォーマットの問題を解決していない
    • そもそもBinaryPackのWGに入らないのも,これらのプロセスで必要な時間(ML対応やMTG参加など)がfrsyukiやその他の開発者陣にいない,というのもある
  • IETFの流れ的に仕様ありきだとそもそも標準化されないんでは?
    • 最近のIETFだとそうじゃなくてもされるらしい?この辺は文化がよく分かってないので,皆??という感じですね

その他

  • こんな事例はいくらでもあるので,こういうことに対応出来る環境をつくっておくべき
    • 商標登録とか,うまくあしらう方法とか身につける

結局コミュニティとしては,標準化とかのプロセスが今走らなければこれらのことを考えなくてよくなるのでハッピーという感じで,走るのであれば今の文字列とかの新しいフォーマットの流れが落ち着くのを待って,という感じです. が,最初のパラグラフに書いた通り,標準化を提案している人にも都合があるので,上手い落としどころがないかと探っているのが現状.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.