BestGems Pickup! 第6回 「daemons」

タグ: bestgems_pickup / 公開: 2013-09-28

拙作のBestGemsから注目のGemを紹介するエントリー。第6回は「daemons」を取り上げる。

概要

daemonsはrubyスクリプトをデーモン化し、外部からコントロール(start, stop等)できるようにするライブラリだ。

daemonsは今日現在、合計ダウンロードランキング46位、デイリーダウンロードランキング66位につけている。

インストール

gem install daemons

使用例

damonesの使い方で一番オーソドックスなのは、制御スクリプトを書いてアプリケーションをデーモン化する方法だ。

アプリケーションmyserver.rbを以下の内容とする。

loop do
	sleep(5)
end

続いて制御スクリプトmyserver_control.rbを以下のように書く。

require 'daemons'

Daemons.run('myserver.rb')

これだけで、myserver.rbをデーモン化し、myserver_control.rbを通じてコントロールできるようになる。

まずアプリケーションを起動するにはstartだ。これでバックグラウンドでアプリケーションが実行される。

ruby myserver_control.rb start

daemonsでは、通常はアプリケーションを重複起動できないようになっており、再度startするとエラーメッセージが出る。

ruby myserver_control.rb start
ERROR: there is already one or more instance(s) of the program running

アプリケーションの状態を表示するにはstatusを使う。動作状況とPIDが表示される。

ruby myserver_control.rb status
myserver.rb: running [pid 16924]

起動しているアプリケーションを停止するにはstopだ。

ruby myserver_control.rb stop

さて、上記の例ではアプリケーションと制御スクリプトを別のスクリプトにしていた。もしアプリケーションに少し手を加えて良いなら、制御スクリプトを分けない書き方もできる。

以下の内容をmyproc_control.rbとする。

require 'daemons'

Daemons.run_proc('foo') do
	loop do
		sleep(5)
	end
end

Daemons.run_proc()はブロックの中身をデーモンとして実行するメソッドだ。引数に与えるのは識別子なので何でもかまわない。

このスクリプトも最初の例と同じようにstartstopで制御することができる。

ruby myproc_control.rb start
ruby myproc_control.rb stop

解説

daemonsを使えば、自分のrubyスクリプトを、わずか2行でデーモン化することが可能だ。自分でrubyでデーモンを書いたことがある人ならありがたみがわかるだろう。サーバや常時起動するアプリケーションを自分で書く機会があるなら、ぜひ抑えておきたいgemである。

補足として、daemonsで可能な操作を以下の表にまとめた。デーモンを操作するための、ひと通りの機能が揃っていることがわかる。

アプリケーションのインスタンス、という遠まわしの表現なのは、アプリケーションを複数起動させることもできるためだ。

操作意味
startアプリケーションのインスタンスを起動する
stopアプリケーションのインスタンスをすべて停止する
restartアプリケーションのインスタンスをすべて停止し、その後に起動させる
reloadアプリケーションのインスタンスすべてにSIGHUPを送信する
runアプリケーションをフォアグラウンドで起動する
zapアプリケーションを停止した状態にする
statusアプリケーションのインスタンスのPIDを表示する

使用例では取り上げなかった機能もある。Daemons.callでRubyスクリプトからデーモンを操作することもできる。またDaemons.daemonizeで実行中のプロセスをデーモン化することも可能だ。詳しくはドキュメントとソースを見てほしい。

この記事をSNSでシェアする
タイトルとURLをコピーする
または投稿画面を開く
Author
Icon
ぺけみさお / xmisao
プログラマ。
Subscription
Recent articles
Related to bestgems_pickup