2014年4月26日土曜日

Golang Cafe #26

4/20(日)に開催された「Golang Cafe #26」に参加してきました。

参加者は主催の +Takashi Yokoyama さん、+Takanobu Hagino さん、ハムエッグさん、私の4名でした。

今回からコンテナ型仮想化環境「Docker」のソースを読み始めました。

DockerがGoで記述されているのは知っていましたが、肝心のDockerを知らなかったので(^^;)、この状態でソースを読み進めると後々ツラいと思い、前日に開催されていた「Docker入門」に参加して、概要だけでも頭に入れて参加しました。

前半はDocker談義や雑談を行い、Dockerソースの総行数を求めたりしました。

後半からエントリーポイントとなるdocker/docker.goを読み始めました。

import部にて、実際にパッケージ名の別名(省略)を行っている例を初めて見ました。

  import (
   ...
   flag "github.com/dotcloud/docker/pkg/mflag"
   ...
  )

別名を"_"にすることで、パッケージ配下の全てのgoファイルを対象にinit()関数が実行されるため、初期化処理に利用できます。

  _ "github.com/dotcloud/docker/pkg/mflag"

const部で定義されているファイル名の拡張子に".pem"が記述されていたり、パッケージ名に"x509"の文字が見受けられるので、電子証明書を使った暗号化通信が行われるようです。

あと、オプション表記に"#"を使うパターンがあるのも初めて知りました。

  bridgeIp = flag.String([]string{"#bip", "-bip"}, ...

dockerは指定するオプションなどによって、3つのモード(init, daemon, client)で起動します。

起動時に以下のファイルが存在すればinitモードで起動します。

  $HOME/.docker/.dockerinit

この判定処理はmain()関数の先頭(=オプション判定よりも先)に記述されています。

  func main() {
      if selfPath := utils.SelfPath(); strings.Contains(selfPath, ".dockerinit") {
          // Running in init mode
          sysinit.SysInit()
          return
      }

"d(-d)"オプションを指定して起動するとdaemonモード、それ以外ならclientモードで起動します。

daemon&clientモード判定のif部はコード量が少しあるため、今回はclientモードを読みました。

if *flDaemon {
    // daemonモードの処理
    ...
} else {
    // clientモードの処理
    ...
}

自分の感覚だと、上記のif部は「コードが長過ぎる・インデントが深過ぎる」と判断して、分岐後の処理を別関数に切り出そうとするのですが、そうなっていない理由を知りたいと思いました。

もしかしたら、

  • ソースリーディング時の流れを考慮しているため。
    • 重複したコードもなく処理も一度しか出現しないので関数化不要?
    • 関数化するとリーディングの流れが中断して(=目線が途切れて)しまう。
  • コンパイラーの最適化に影響があるため。
    • 生成されるバイナリーファイルのサイズが増加する?
    • バイナリーファイル実行時の速度やメモリ消費量に影響がある。

といった理由があるのかもしれません。

余談ですが、自分は普段からソースはlessやvimで読み書きしているのですが、lessでソースを見ていたら横山さんに驚かれてしまいました...(^^;)

次回も引き続きDockerソースを読み進める予定のようです。

P.S.情報処理技術者試験後のGolang Cafeはやはりキツかったですね...(^^;)

[2014.04.27] 余談にて横山さんからのコメントを反映して、P.S.を追加しました。

0 件のコメント: