ElixirでThriftで定義した構造体にアクセスする


1. ElixirからもThriftをさわりたい

Elixirから、thriftを利用してデータのやり取りしたいなー、と見ていましたが、erlangだとあるけど、elixirだと現在は利用できないようです。
サポートされるのを待ちつつも以下のようなpinterest製のライブラリを利用してみます。

2. Riffedの特徴

以下のような特徴を持っているみたいです。

  1. thriftコードから、erlangのコードを自動生成するMixタスク[mix compile.thrift]を提供
  2. Riffed.Structを利用して、thriftで定義、erlangで生成した構造体にElixirからアクセスできる機能を提供
  3. Riffed.Server, Riffed.Clientを提供することで、生成したコードを利用したデータ通信の簡易サーバを簡単に構築できる機能を提供

最初は、1, 2だけなのかな、と思っていましたが、3もあるのですね。

3. 利用してみよう

とはいえ、1, 2は比較的にお手軽に利用できたのでちょっと触ってみました。

3-1. dependenciesを追加

チュートリアルにあるようにsubmodulesをtrueにします。これで落ちてくるソースがけっこうでかかったです。。

mix.exs
  defp deps do
    [
      {:riffed, github: "pinterest/riffed", tag: "1.0.0", submodules: true}
    ]
  end

3-2. thriftコードを用意

mixプロジェクトにthriftというディレクトリを作成し、そこに拡張子がthriftのソースコードを配置します。

thrift/example.thrift
struct MyChatMessage
{
  1: i32 senderId,
  2: i32 recieverId,
  3: string message
}

service MyChatService
{
  void sendMessage(1: MyChatMessage message);
  void recieveMessage(1: MyChatMessage message)
}

3-3. erlangコードを自動生成する

3-1実施後に、mixでタスクが追加されます。3-2.で定義した情報を利用して自動生成のタスクを実行します。

mix compile.thrift

これを実行すると、srcというフォルダが自動で作成されたソースコードが配置されます。

3-4. elixirから、生成したコードを利用してみる

下記のように、Elixirコードを用意します。

lib/my_chat_message.ex
defmodule MyChatMessage do
    use Riffed.Struct, example_types: [:MyChatMessage]
end

簡易に利用できるかだけ見たいので、iex -S mixで見てみました。

$ iex -S mix

iex(1)> MyChatMessage.MyChatMessage.__struct__

%MyChatMessage.MyChatMessage{message: :undefined, recieverId: :undefined,
 senderId: :undefined}

iex(2)> message = %MyChatMessage.MyChatMessage{message: "test", recieverId: 1, senderId: 2}

%MyChatMessage.MyChatMessage{message: "test", recieverId: 1, senderId: 2}

と、このように、構造体へのアクセスができることが確認できました^^


サンプルは以下においています。


次はRiffedのServer, Clientも見てみようと思います。

Cassandraとかとも連携できそうですし、楽しそうですね^^

本日は以上となります。