2014年5月17日土曜日

Golang Cafe #29を開催しました。

Golang Cafe #29を開催しました。

今回は、#27に引き続き、dockerのソースコードを読み進めました。

前回は、deamon側に向かって、リクエストを飛ばすクライアント側のソースコードを読みましたので、docker/docker.goの98行目から開始しました。
(-d、-deamonオプションを付けた場合に動作する部分)

dockerにはHandlerという内部コマンド(?)があって、最初にHandlerを実行するための準備をします。(builtins/builtins.go)内部コマンドはコマンドの名前(例:initserverなど)をキーにして実行する関数を保持するmapとして定義されていて、各処理の時に、名前を指定して呼び出します。
最初は、"initserver"、"init_networkdriver"、"serveapi"の3つが登録されています。

initserverの中で、クライアントからのリクエストに対するHandlerが登録されます。

ただ、読み方としてコツがあって、以前にもでてきた、「goroutinesの切り替わり」を考えて処理の順番を考えないといけません。

したがって、登録したHandlerの順番としては、最初に"serveapi"が実行されます。これは、docker.goの133行目付近はgoroutineになっていますので、バックグラウンドで動くことになります。よって、先にdocker.goの179行目にある、job.Run()が実行されることになります。docker.goを見る限りでは、runtime.GOMAXPROCS()を呼び出していませんのでMAXPROCSは1で動作していますから、「明示的なスレッドのブロック」が無い限りは"serveapi"が動作すると思われます。(ということは、runtime.GOMAXPROCS()を呼び出すとまともに動作しないのかも…?)

job.Run()の中では、登録されているHandlerを呼び出すので、初見では、何かの関数か?と思うかもしれませんが、関数型のmapの関数を呼び出すような仕組みなので、呼び出しの部分は勘違いしないようにしなければいけないと思います。

以前のクライアントからUnixソケットを使って接続するようになっていましたが、docker.goの155行目でacceptconnectionsが実行されています。
(中で、net.DialUnix()されています。(Unixソケットってサーバ、クライアントどちらもDialなのか…?))

正直、dockerのソースコードは読みづらい…。俺だけか?

次回は、各コマンドの内部を読み解いていく予定です。