Riak Source Code Reading #2: Erlang Client

N
riak-erlang-client
                                2012/12/11 @nobu_k




Thursday, December 13, 12
自己紹介
                    • 久保田展行(@nobu_k)

                    • Preferred Infrastructure(PFI, ピーFI)

                            • Architect: Sedue, Bazil
                    • DB, Distributed Systems, C++
                    • Erlang素人

                            • Riakのコードを読みながら勉強したい
                    •       IIDX




Thursday, December 13, 12
読むもの

                    • riak-erlang-client
                    • +周辺のコード

                            • riak_pb (pb=Protocol Buffers)
                            • riak_kv
                             • リクエストを処理してる部分


Thursday, December 13, 12
riak-erlang-client



Thursday, December 13, 12
概要


                    • Erlang用のクライアント

                    • ソースコード

                            • git://github.com/basho/riak-erlang-
                              client.git



Thursday, 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
                            • API



Thursday, December 13, 12
riakc_obj.erl



Thursday, 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.erl



Thursday, 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
1 of 25

Recommended

NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 3.4.0対応) by
NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 3.4.0対応)NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 3.4.0対応)
NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 3.4.0対応)fisuda
239 views55 slides
Perlと出会い、Perlを作る by
Perlと出会い、Perlを作るPerlと出会い、Perlを作る
Perlと出会い、Perlを作るgoccy
3.1K views24 slides
NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 3.6.0対応) by
NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 3.6.0対応)NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 3.6.0対応)
NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 3.6.0対応)fisuda
325 views55 slides
Java 7 invokedynamic の概要 by
Java 7 invokedynamic の概要Java 7 invokedynamic の概要
Java 7 invokedynamic の概要Taku Miyakawa
8.6K views39 slides
はてなブックマーク in Scala by
はてなブックマーク in Scalaはてなブックマーク in Scala
はてなブックマーク in ScalaLintaro Ina
68.8K views40 slides
コンピューティングとJava~なにわTECH道 by
コンピューティングとJava~なにわTECH道コンピューティングとJava~なにわTECH道
コンピューティングとJava~なにわTECH道なおき きしだ
2.1K views82 slides

More Related Content

What's hot

UnityのLambda API を Dynamo DB APIっぽく使う by
UnityのLambda API を Dynamo DB APIっぽく使うUnityのLambda API を Dynamo DB APIっぽく使う
UnityのLambda API を Dynamo DB APIっぽく使うKinose Tomohito
1K views34 slides
NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 3.2.0対応) by
NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 3.2.0対応)NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 3.2.0対応)
NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 3.2.0対応)fisuda
506 views51 slides
MySQL de NoSQL Fukuoka by
MySQL de NoSQL FukuokaMySQL de NoSQL Fukuoka
MySQL de NoSQL FukuokaRyusuke Kajiyama
1.7K views9 slides
ラムダと invokedynamic の蜜月 by
ラムダと invokedynamic の蜜月ラムダと invokedynamic の蜜月
ラムダと invokedynamic の蜜月Taku Miyakawa
11.2K views51 slides
NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 1.13.0対応) by
NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 1.13.0対応)NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 1.13.0対応)
NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 1.13.0対応)fisuda
1.5K views46 slides
なぜリアクティブは重要か #ScalaMatsuri by
なぜリアクティブは重要か #ScalaMatsuriなぜリアクティブは重要か #ScalaMatsuri
なぜリアクティブは重要か #ScalaMatsuriYuta Okamoto
7.9K views81 slides

What's hot(11)

UnityのLambda API を Dynamo DB APIっぽく使う by Kinose Tomohito
UnityのLambda API を Dynamo DB APIっぽく使うUnityのLambda API を Dynamo DB APIっぽく使う
UnityのLambda API を Dynamo DB APIっぽく使う
Kinose Tomohito1K views
NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 3.2.0対応) by fisuda
NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 3.2.0対応)NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 3.2.0対応)
NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 3.2.0対応)
fisuda 506 views
ラムダと invokedynamic の蜜月 by Taku Miyakawa
ラムダと invokedynamic の蜜月ラムダと invokedynamic の蜜月
ラムダと invokedynamic の蜜月
Taku Miyakawa11.2K views
NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 1.13.0対応) by fisuda
NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 1.13.0対応)NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 1.13.0対応)
NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 1.13.0対応)
fisuda 1.5K views
なぜリアクティブは重要か #ScalaMatsuri by Yuta Okamoto
なぜリアクティブは重要か #ScalaMatsuriなぜリアクティブは重要か #ScalaMatsuri
なぜリアクティブは重要か #ScalaMatsuri
Yuta Okamoto7.9K views
NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 1.14.0対応) by fisuda
NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 1.14.0対応)NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 1.14.0対応)
NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 1.14.0対応)
fisuda 1.1K views
NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 3.1.0対応) by fisuda
NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 3.1.0対応)NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 3.1.0対応)
NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 3.1.0対応)
fisuda 318 views
NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 2.0.0対応) by fisuda
NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 2.0.0対応)NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 2.0.0対応)
NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 2.0.0対応)
fisuda 262 views
NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 1.15.0対応) by fisuda
NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 1.15.0対応)NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 1.15.0対応)
NGSIv1 を知っている開発者向けの NGSIv2 の概要 (Orion 1.15.0対応)
fisuda 669 views
Shibuya.lisp #28: 仮題: R について by tnoda
Shibuya.lisp #28: 仮題: R についてShibuya.lisp #28: 仮題: R について
Shibuya.lisp #28: 仮題: R について
tnoda2.6K views

Similar to Riak Source Code Reading #2: Erlang Client

Web Operations and Perl kansai.pm#14 by
Web Operations and Perl kansai.pm#14Web Operations and Perl kansai.pm#14
Web Operations and Perl kansai.pm#14Masahiro Nagano
2.1K views55 slides
第8回KPF発表資料 by
第8回KPF発表資料第8回KPF発表資料
第8回KPF発表資料cryks
4.3K views26 slides
Web技術勉強会 第25回 by
Web技術勉強会 第25回Web技術勉強会 第25回
Web技術勉強会 第25回龍一 田中
649 views20 slides
tcpdump & xtrabackup @ MySQL Casual Talks #1 by
tcpdump & xtrabackup @ MySQL Casual Talks #1tcpdump & xtrabackup @ MySQL Casual Talks #1
tcpdump & xtrabackup @ MySQL Casual Talks #1Ryosuke IWANAGA
5.5K views39 slides
Kai = (Dynamo + memcache API) / Erlang by
Kai = (Dynamo + memcache API) / ErlangKai = (Dynamo + memcache API) / Erlang
Kai = (Dynamo + memcache API) / ErlangTakeru INOUE
1.5K views49 slides
RestKitの紹介 - Webサービスのクライアント実装補助フレームワーク - by
RestKitの紹介 - Webサービスのクライアント実装補助フレームワーク -RestKitの紹介 - Webサービスのクライアント実装補助フレームワーク -
RestKitの紹介 - Webサービスのクライアント実装補助フレームワーク -次朗 永島
6.2K views22 slides

Similar to Riak Source Code Reading #2: Erlang Client(20)

Web Operations and Perl kansai.pm#14 by Masahiro Nagano
Web Operations and Perl kansai.pm#14Web Operations and Perl kansai.pm#14
Web Operations and Perl kansai.pm#14
Masahiro Nagano2.1K views
第8回KPF発表資料 by cryks
第8回KPF発表資料第8回KPF発表資料
第8回KPF発表資料
cryks4.3K views
Web技術勉強会 第25回 by 龍一 田中
Web技術勉強会 第25回Web技術勉強会 第25回
Web技術勉強会 第25回
龍一 田中649 views
tcpdump & xtrabackup @ MySQL Casual Talks #1 by Ryosuke IWANAGA
tcpdump & xtrabackup @ MySQL Casual Talks #1tcpdump & xtrabackup @ MySQL Casual Talks #1
tcpdump & xtrabackup @ MySQL Casual Talks #1
Ryosuke IWANAGA5.5K views
Kai = (Dynamo + memcache API) / Erlang by Takeru INOUE
Kai = (Dynamo + memcache API) / ErlangKai = (Dynamo + memcache API) / Erlang
Kai = (Dynamo + memcache API) / Erlang
Takeru INOUE1.5K views
RestKitの紹介 - Webサービスのクライアント実装補助フレームワーク - by 次朗 永島
RestKitの紹介 - Webサービスのクライアント実装補助フレームワーク -RestKitの紹介 - Webサービスのクライアント実装補助フレームワーク -
RestKitの紹介 - Webサービスのクライアント実装補助フレームワーク -
次朗 永島6.2K views
fluentd を利用した大規模ウェブサービスのロギング by Yuichi Tateno
fluentd を利用した大規模ウェブサービスのロギングfluentd を利用した大規模ウェブサービスのロギング
fluentd を利用した大規模ウェブサービスのロギング
Yuichi Tateno27.2K views
Ruby で扱う LDAP のススメ by Kazuaki Takase
Ruby で扱う LDAP のススメRuby で扱う LDAP のススメ
Ruby で扱う LDAP のススメ
Kazuaki Takase13.3K views
~knitr+pandocではじめる~『R MarkdownでReproducible Research』 by Nagi Teramo
~knitr+pandocではじめる~『R MarkdownでReproducible Research』~knitr+pandocではじめる~『R MarkdownでReproducible Research』
~knitr+pandocではじめる~『R MarkdownでReproducible Research』
Nagi Teramo31.4K views
HashiCorpのNomadを使ったコンテナのスケジューリング手法 by Masahito Zembutsu
HashiCorpのNomadを使ったコンテナのスケジューリング手法HashiCorpのNomadを使ったコンテナのスケジューリング手法
HashiCorpのNomadを使ったコンテナのスケジューリング手法
Masahito Zembutsu11.6K views
Cookpad 17 day Tech internship 2017 言語処理系入門 Rubyをコンパイルしよう by Koichi Sasada
Cookpad 17 day Tech internship 2017 言語処理系入門 RubyをコンパイルしようCookpad 17 day Tech internship 2017 言語処理系入門 Rubyをコンパイルしよう
Cookpad 17 day Tech internship 2017 言語処理系入門 Rubyをコンパイルしよう
Koichi Sasada15.4K views
Integral - New O/R Mapper for Common Lisp by fukamachi
Integral - New O/R Mapper for Common LispIntegral - New O/R Mapper for Common Lisp
Integral - New O/R Mapper for Common Lisp
fukamachi13.4K views
20130626 kawasaki.rb NKT77 by nkt77
20130626 kawasaki.rb NKT7720130626 kawasaki.rb NKT77
20130626 kawasaki.rb NKT77
nkt77178 views
Javaはどのように動くのか~スライドでわかるJVMの仕組み by Chihiro Ito
Javaはどのように動くのか~スライドでわかるJVMの仕組みJavaはどのように動くのか~スライドでわかるJVMの仕組み
Javaはどのように動くのか~スライドでわかるJVMの仕組み
Chihiro Ito67.2K views

More from nobu_k

Elasticsearchと機械学習を実際に連携させる by
Elasticsearchと機械学習を実際に連携させるElasticsearchと機械学習を実際に連携させる
Elasticsearchと機械学習を実際に連携させるnobu_k
30K views40 slides
機械学習を利用したちょっとリッチな検索 by
機械学習を利用したちょっとリッチな検索機械学習を利用したちょっとリッチな検索
機械学習を利用したちょっとリッチな検索nobu_k
16.6K views33 slides
4th PFI System reading by
4th PFI System reading4th PFI System reading
4th PFI System readingnobu_k
1.7K views16 slides
Goraft and InfluxDB by
Goraft and InfluxDBGoraft and InfluxDB
Goraft and InfluxDBnobu_k
10.4K views22 slides
Transactional Information Systems入門 by
Transactional Information Systems入門Transactional Information Systems入門
Transactional Information Systems入門nobu_k
3.7K views54 slides
Paxos by
PaxosPaxos
Paxosnobu_k
2.7K views64 slides

More from nobu_k(8)

Elasticsearchと機械学習を実際に連携させる by nobu_k
Elasticsearchと機械学習を実際に連携させるElasticsearchと機械学習を実際に連携させる
Elasticsearchと機械学習を実際に連携させる
nobu_k30K views
機械学習を利用したちょっとリッチな検索 by nobu_k
機械学習を利用したちょっとリッチな検索機械学習を利用したちょっとリッチな検索
機械学習を利用したちょっとリッチな検索
nobu_k16.6K views
4th PFI System reading by nobu_k
4th PFI System reading4th PFI System reading
4th PFI System reading
nobu_k1.7K views
Goraft and InfluxDB by nobu_k
Goraft and InfluxDBGoraft and InfluxDB
Goraft and InfluxDB
nobu_k10.4K views
Transactional Information Systems入門 by nobu_k
Transactional Information Systems入門Transactional Information Systems入門
Transactional Information Systems入門
nobu_k3.7K views
Paxos by nobu_k
PaxosPaxos
Paxos
nobu_k2.7K views
Suffix Array@Solr勉強会 by nobu_k
Suffix Array@Solr勉強会Suffix Array@Solr勉強会
Suffix Array@Solr勉強会
nobu_k4K views
第一回MongoDBソースコードリーディング by nobu_k
第一回MongoDBソースコードリーディング第一回MongoDBソースコードリーディング
第一回MongoDBソースコードリーディング
nobu_k1.2K views

Riak Source Code Reading #2: Erlang Client

  • 1. riak-erlang-client 2012/12/11 @nobu_k Thursday, December 13, 12
  • 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