Yokohama.rb Monthly Meetup #76 に参加した

2017-01-14(土)の Yokohama.rb Monthly Meetup #76 に参加したので、メモを書きます。1 週間たってしまった。

yokohamarb.doorkeeper.jp

Ruby レシピブック

今回はレシピ 244 から 247 まで読みました。システム寄りの話題が中心です。

レシピ 244

スレッドファイバの扱いかたについてです。

スレッドを使うときに気をつけるべき点は次のようなところでしょう。

  • あるスレッドが別のスレッドの変数を操作しないように、Thread#fork の引数としてスレッド固有のローカル変数を渡す
  • メインスレッドが勝手に終了するのを防ぐため Thread#join でスレッドが終了するのを待つ

ファイバは軽量スレッドのようなものです。スレッドは自動で他スレッドに制御が移りますが、ファイバが持つコードを実行するには Fiber#resume を実行し、制御を呼び出し元に戻すには Fiber#yield を実行する必要があります。Enumerable#each など内部イテレータをジェネレータのような外部イテレータに変換するコードとともに紹介されていました。

ちなみに、Ruby 1.9 以降では組み込みの Enumerator をジェネレータとして使うことができます。

sentence =<<EOF
lorem ipsum
hoge fuga fizz bazz
EOF
enumerator = sentence.each_line  # Enumerator を返す
loop { p enumerator.next }
# => "lorem ipsum\n"
# => "hoge fuga fizz bazz\n"

また、レシピのサンプルコードで Object#__send__ というメソッドが使われていました。これは、send という名前が一般的で再定義されやすいことから定義された Object#send の別名ということです。

レシピ 245

プロセスのフォークについてです。

レシピ内では fork して exec するサンプルコードが紹介されていました。この用途なら Kernel.#spawn でもよいという話がありました。子プロセスの終了を待つなら Process.waitpid2 を使う必要があります。

pid = spawn('job')
exitpid, status = *Process.waitpid2(pid)  # 'job' が終了するまで待つ

レシピ 246

プロセスがシグナルを受けたときの動作を設定するシグナルハンドラについてです。

有名な SIGINT などの他に SIGUSR1, SIGUSR2 というはシグナルがあって、これはユーザ定義用のものだそうです(参照:シグナル (ソフトウェア) - Wikipedia)。

Pry など REPL 上で Singal.trap(:USR1) { puts 'USR1' } などとして、killSIGUSR1 を送ると、シグナルハンドラが動作していることが確かめられます。

レシピ 247

プロセスをデーモン化する方法についてです。

注意点として、デーモンの場合、必ず Kernel.#exit! で終了するようにします。exit!ensure 節など後処理も飛ばしてプロセスを終了します。これを使わないと stdio ライブラリのバッファが 2 回フラッシュされてしまうなどの問題が起きるそうです。

そもそもなぜデーモンなのか? nohup ではだめなのか?という話に展開して、次のページを皆で見ていました。

もくもく

後半はもくもく会でした。僕は swagger-docsSwagger UI を使って、Rails で作った API のドキュメント化を試していました。

懇親会

miyohide さん誕生日おめでとうございました。


次回は 2017-02-18(土)です。次のリンクから申し込めます。

yokohamarb.doorkeeper.jp