More Related Content
Similar to Riak Source Code Reading #2: Erlang Client
Similar to Riak Source Code Reading #2: Erlang Client(20)
Riak Source Code Reading #2: Erlang Client
- 2. 自己紹介
• 久保田展行(@nobu_k)
• Preferred Infrastructure(PFI, ピーFI)
• Architect: Sedue, Bazil
• DB, Distributed Systems, C++
• Erlang素人
• Riakのコードを読みながら勉強したい
• IIDX
Thursday, December 13, 12
- 3. 読むもの
• riak-erlang-client
• +周辺のコード
• riak_pb (pb=Protocol Buffers)
• riak_kv
• リクエストを処理してる部分
Thursday, December 13, 12
- 5. 概要
• Erlang用のクライアント
• ソースコード
• git://github.com/basho/riak-erlang-
client.git
Thursday, December 13, 12
- 6. 使い方
> {ok, Pid} = riakc_pb_socket:start_link(Address, Port).
{ok,<0.34.0>}
> riakc_pb_socket:ping(Pid).
pong
• https://github.com/basho/riak-erlang-
client
• githubのREADMEがわかりやすい
• Portはconfigのriak_api/pb_portの値
• 返値のPidをriakc_pb_socketに渡す感じで
Thursday, December 13, 12
- 7. 本日のターゲット
• riakc_obj.erl
• 値
• riakc_pb_socket.erl
• API
Thursday, December 13, 12
- 9. riak_obj.erl
> Object = riakc_obj:new(<<"groceries">>, <<"mine">>,
<<"eggs & bacon">>).
{riakc_obj,<<"groceries">>,<<"mine">>,undefined,
[],undefined,<<"eggs & bacon">>}
• Riakに保存される値の情報
• riakc_obj:new(Bucket, Key, Value).
• getで取得する値もこれ
Thursday, December 13, 12
- 10. 中身
-type bucket() :: binary().
-type key() :: binary() | 'undefined'.
-type vclock() :: binary().
-type metadata() :: dict().
-type content_type() :: string().
-type value() :: binary().
-type contents() :: [{metadata(), value()}].
-record(riakc_obj, {
bucket :: bucket(),
key :: key(),
vclock :: vclock(),
contents :: contents(),
updatemetadata :: dict(),
updatevalue :: value()
}).
Thursday, December 13, 12
- 11. 関数とか
• recordの中身に対する操作がほとんど
• ところで
dict:store(?MD_CTYPE, CT, M1)
?MD_CTYPEの頭に付いてる?はなに?
追記:マクロと教えて頂きました!
Thursday, December 13, 12
- 12. set系の関数はどこ?
• contentなどをセットする関数はない
• 代わりにupdateがある
• 今の値と更新後の値を別扱い
• newに渡した値はupdateに入る
• putするとupdateの値が保存される
• Riakから元のcontentsは消える
Thursday, December 13, 12
- 13. なんでcontentsは配列?
• コンフリクトしたときのため
• riakc_obj:value_count(Obj).
• riakc_obj:get_values(Obj).
• コンフリクト除去
• updateに適切な値を入れる
• 値を選択 or 適切にマージ
Thursday, December 13, 12
- 15. riakc_pb_socket.erl
• RPC(?)の部分
• 読む順序
• 通信っぽい部分
• CRUD関係
• list系
• mapredはMasahitoさんから解説がありそう
• 後は実際にコードを読みながら・・・
Thursday, December 13, 12
- 16. 全体的なメモ1
• ***_optionsの書き方が綺麗
• リスト+中身のパターンマッチングで再帰
• rpb***req
• riak_pbのriak_kv.protoを参照
• コードの40%がテスト
• Riakが起動してることが前提?
Thursday, December 13, 12
- 17. 全体的なメモ2
• 基本はgen_server:call
• 値の入ったタプルを投げてるだけ
• {req, #pbなrecord, Timeout}
Thursday, December 13, 12
- 18. get/putの疑問点
• encode
• putではencodeした値を送っている
• getは受け取った値をそのまま返す
• どこかでdecodeされてる?
• そもそもgen_server:callを理解してなかった
• 後述しますがhandle_infoの中でレスポンスを処理してます
Thursday, December 13, 12
- 19. get: サーバ側の処理
• リクエストの処理場所が分からない
• rpb***reqを処理してるとこを探す
• →riak_kv/riak_kv_pb_object.erl
• processのgetreqを処理してるやつ
• 中でriak:local_clientのgetを呼んでる
• が、今は追わなくてよさそう
Thursday, December 13, 12
- 20. get: riak_objectの処理
• local_clientが返した値の処理を追う
• riakc_objじゃなくてriak_object
• riak_pb_kv_codec:encode_contents
• 値を返す前にPBにエンコードしてる
• やっぱりclientでデコードが必要!?
• put側の処理も見てみる
• TODO: vclockに対してなんかやってるのも気になる・・・
Thursday, December 13, 12
- 21. put: ちょっと寄り道
• clientがエンコードした値の処理され方
• riak_kv_pb_object.erl
• process putreqの中
• update_rpbcontentで値を取り出す
• ここでは明示的にデコードしてる
%% Update riak_object with the pbcontent provided
update_rpbcontent(O0, RpbContent) ->
{MetaData, Value} =
riak_pb_kv_codec:decode_content(RpbContent),
O1 = riak_object:update_metadata(O0, MetaData),
•
riak_object:update_value(O1, Value).
Thursday, December 13, 12
- 22. get: process_response
• clientに戻る
• decode_contentsを呼んでるとこ発見
• handle_info からの process_response
• (再)そもそもgen_server:callを理解してなかった
process_response(#request{msg = #rpbgetreq{bucket = Bucket, key = Key}},
#rpbgetresp{content = RpbContents, vclock = Vclock},
State) ->
Contents = riak_pb_kv_codec:decode_contents(RpbContents),
{reply, {ok, riakc_obj:new_obj(Bucket, Key, Vclock, Contents)},
State};
Thursday, December 13, 12
- 23. list_keys
• 中身はstream_list_keysとwait
• strean_list_keys
• キーをreceiveしまくる戦法
• 対応するのはriak_kv_pb_bucket.erl
• riak_clientのstream_list_keysを呼び出し
• 中身はまさかのmapred!?
Thursday, December 13, 12
- 25. まとめ
• riak-erlang-client
• Protocol Buffersを使ってる
• riak_kv/src/riak_kv_pb_{bucket,object}.erlに対応
• すごいエロ本(Learn You Some Erlang for Great Good!)は神
• 分からないところを調べながらやってました!
• 翻訳した@ymotongpooさんも神
• TODO
• vclockまわり
• サーバ側のリクエスト処理部をもうちょっと追いたい
Thursday, December 13, 12