• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Riak Source Code Reading #2: Erlang Client
 

Riak Source Code Reading #2: Erlang Client

on

  • 1,016 views

 

Statistics

Views

Total Views
1,016
Views on SlideShare
1,016
Embed Views
0

Actions

Likes
1
Downloads
6
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Riak Source Code Reading #2: Erlang Client Riak Source Code Reading #2: Erlang Client Presentation Transcript

    • riak-erlang-client 2012/12/11 @nobu_kThursday, December 13, 12
    • 自己紹介 • 久保田展行(@nobu_k) • Preferred Infrastructure(PFI, ピーFI) • Architect: Sedue, Bazil • DB, Distributed Systems, C++ • Erlang素人 • Riakのコードを読みながら勉強したい • IIDXThursday, December 13, 12
    • 読むもの • riak-erlang-client • +周辺のコード • riak_pb (pb=Protocol Buffers) • riak_kv • リクエストを処理してる部分Thursday, December 13, 12
    • riak-erlang-clientThursday, December 13, 12
    • 概要 • Erlang用のクライアント • ソースコード • git://github.com/basho/riak-erlang- client.gitThursday, December 13, 12
    • 使い方 > {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
    • 本日のターゲット • riakc_obj.erl • 値 • riakc_pb_socket.erl • APIThursday, December 13, 12
    • riakc_obj.erlThursday, December 13, 12
    • 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
    • 中身 -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
    • 関数とか • recordの中身に対する操作がほとんど • ところで dict:store(?MD_CTYPE, CT, M1) ?MD_CTYPEの頭に付いてる?はなに? 追記:マクロと教えて頂きました!Thursday, December 13, 12
    • set系の関数はどこ? • contentなどをセットする関数はない • 代わりにupdateがある • 今の値と更新後の値を別扱い • newに渡した値はupdateに入る • putするとupdateの値が保存される • Riakから元のcontentsは消えるThursday, December 13, 12
    • なんでcontentsは配列? • コンフリクトしたときのため • riakc_obj:value_count(Obj). • riakc_obj:get_values(Obj). • コンフリクト除去 • updateに適切な値を入れる • 値を選択 or 適切にマージThursday, December 13, 12
    • riakc_pb_socket.erlThursday, December 13, 12
    • riakc_pb_socket.erl • RPC(?)の部分 • 読む順序 • 通信っぽい部分 • CRUD関係 • list系 • mapredはMasahitoさんから解説がありそう • 後は実際にコードを読みながら・・・Thursday, December 13, 12
    • 全体的なメモ1 • ***_optionsの書き方が綺麗 • リスト+中身のパターンマッチングで再帰 • rpb***req • riak_pbのriak_kv.protoを参照 • コードの40%がテスト • Riakが起動してることが前提?Thursday, December 13, 12
    • 全体的なメモ2 • 基本はgen_server:call • 値の入ったタプルを投げてるだけ • {req, #pbなrecord, Timeout}Thursday, December 13, 12
    • get/putの疑問点 • encode • putではencodeした値を送っている • getは受け取った値をそのまま返す • どこかでdecodeされてる? • そもそもgen_server:callを理解してなかった • 後述しますがhandle_infoの中でレスポンスを処理してますThursday, December 13, 12
    • get: サーバ側の処理 • リクエストの処理場所が分からない • rpb***reqを処理してるとこを探す • →riak_kv/riak_kv_pb_object.erl • processのgetreqを処理してるやつ • 中でriak:local_clientのgetを呼んでる • が、今は追わなくてよさそうThursday, December 13, 12
    • get: riak_objectの処理 • local_clientが返した値の処理を追う • riakc_objじゃなくてriak_object • riak_pb_kv_codec:encode_contents • 値を返す前にPBにエンコードしてる • やっぱりclientでデコードが必要!? • put側の処理も見てみる • TODO: vclockに対してなんかやってるのも気になる・・・Thursday, December 13, 12
    • 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
    • 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
    • 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
    • まとめThursday, December 13, 12
    • まとめ • 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