Posted at
D言語Day 19

msgpack-rpc-dで泣いた話

More than 3 years have passed since last update.


D言語は言語仕様は良いけどライブラリがダメ

いろんな人(偏ってる可能性大)がそんなこと言ってますね。バイトで初めてD言語を触ったときもそんな風に思ってました。

複数ノードでの並列処理に使えるはずのstd.concurrencyも、現状では複数ノードに対応していなかったりといろいろ悲しい思いをします。

じゃあてめーが書けよって言うのはなしで

そんなことがあるので、複数ノードでの並列処理のための通信にはシンプルで使いやすいMessagePack-RPCを使いたいっていう発想が出てくるかと思います(他のもあるけど)。


そこで登場するmsgpack-rpc-d

最初はDUBのパッケージとして無かったのですが、@repeatedlyさんに連絡したら入れてもらえました。感謝。

msgpack-rpc-dはvibe.dを非同期I/Oライブラリとして使っていますが、DUBにパッケージとして入れてもらえたのでそんなことは気にせずに簡単に使えます。

お手持ちのdub.jsonに


dub.json

{

"dependencies": {
"msgpack-rpc": ">=0.1.1"
}
}

と書くだけで使えるようになります。


msgpack-rpc-dの使い方

これ見ないでREADME.mdを見てもらったほうが早いかもしれません。

単純に接続してRPCするだけなら簡単です。

以下のコードは、127.0.0.1のポート12345に対してRPCを行うような例です。


client.d

import msgpack;

import msgpackrpc.client;

void main(string[] args)
{
auto client = new TCPClient(Endpoint(12345, "127.0.0.1"));

// 戻り値があるRPC(同期)
client.call!(int)("foo", 42);

// 戻り値がないRPC
client.notify("bar", 42);
}


サーバでは、RPCをクラスのメンバ関数に対する呼び出しとして扱えます。


server.d

import msgpack;

import msgpackrpc.server;

class Server
{
int foo(int arg)
{
return arg * 2;
}
}

void main(string[] args)
{
auto server = new TCPServer!(Server)(new Server);

server.listen(Endpoint(12345, "127.0.0.1"));
server.start();
}



ところが

現在(2014/12/19)のmsgpack-rpc-dでは、一度に4096バイト以上のデータを受信するとブロックしてしまうという不具合があります。

これは自分がGitHub上のissueに投稿して調査してもらっていますが、どうやらvibe.dの問題のようです。


良いライブラリなのに…

簡単かつ綺麗にMessagePack-RPCを使える良いライブラリなのですが、依存ライブラリの影響を食らってて悲しいです。

まぁそんな話を某氏に書いてよって言われたわけです(:3[__]