3
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

[Ruby] gem の daemons の利用サンプル

Last updated at Posted at 2013-11-30

ruby で書いたメソッドを daemn 化するのに daemons という gem を使ってみた。

最終的には 上の gist 中の testdaemon_2.rb の形に。
工夫をしたのは次の2点。

  1. log を カレントフォルダの test.log に出す。
  2. 実行する task の処理の途中で処理が中断されないようにする。

daemons の homepage や github にあるサンプルを流用しただけは、これらの点は達成できない。

以下 testdaempn_2.rb を転載する。

testdaemon_2.rb
# -*- coding: utf-8 -*-

# See
#   http://snippets.aktagon.com/snippets/212-how-to-create-a-daemon-process-using-ruby-and-the-daemons-rubygem
#   > How to create a daemon process using Ruby and the daemons RubyGem
#
#   http://wokowa.net/blog/archives/88
#   > Rubyのdaemonsでloggerからログ出す方法がよく分からなかった話
#
#   http://stackoverflow.com/questions/11237815/ruby-cant-write-to-logs-in-daemons
#   > What does daemons internally do with my daemons?
#
#   http://stackoverflow.com/questions/12266645/ruby-daemons-soft-stop
#   > Ruby daemons soft stop
#
# 開始
#  ruby testdaemon_2.rb start
# 再起動
#  ruby testdaemon_2.rb restart
# 終了
#  ruby testdaemon_2.rb stop
#
# -----------------------------------------
# task(logger) の処理を繰り返し実行する。
# task 実行中に daemon の stop , restart の指示, kill pid をされても、
# task の処理が途中で中断されることが無い様にした。
#
# $ tail -f test.log や $ tail -f test.rb.output を別コンソールで実行しながら
# damon の stop, resatret, kill pid を行うと様子がよくわかる。
#
# -----------------------------------------
# ruby: ruby 1.9.3p484 (2013-11-22 revision 43786) [i386-darwin9.8.0]
# gem:  daemons (1.1.9)

require 'rubygems'
require 'daemons'
require 'logger'

CWD = File.expand_path(File.dirname(__FILE__))

STDOUT.sync = true
STDERR.sync = true

def task(logger)
  # 時間がかかる処理を定義。
  # 処理の途中で daemon の stop, restart を行いやすくしてある。
  logger.info 'start task'
  sleep 2; STDOUT.puts "# ------- task start #{Time.now}"
  sleep 2; STDOUT.puts "#      -- stdout #{Time.now}"
  sleep 2; STDERR.puts "#      -- stderr #{Time.now}"
  sleep 2; STDOUT.puts "# ------- task end   #{Time.now}"
  logger.info 'fnish task'
end

# ------------------
def get_logger
  ret = Logger.new('test.log')
  ret.level = Logger::INFO
  ret
end

def log_info(logger, str)
  logger = get_logger unless logger
  logger.info str
  logger
end

def show_message(str)
  puts str
  log_info(nil, str)
end

options = {
  log_output: true,   # stdout, stderr を test.rb.output に保持する
  multiple:   false,
  ontop:      false,
  backtrace:  true,
  monitor:    false
}
Daemons.run_proc('test.rb', # name of daemon
                 options) do
  stopped = false
  logger = nil

  Signal.trap(:INT)  { stopped = true; show_message 'SIGINTを受信' }
  Signal.trap(:QUIT) { stopped = true; show_message 'SIGQUITを受信' }
  Signal.trap(:KILL) { stopped = true; show_message 'SIGKILLを受信' }
  Signal.trap(:TERM) { stopped = true; show_message 'SIGTERMを受信' }

  Dir.chdir CWD
  until stopped
    logger = show_message 'Start Daemon' if logger.nil?
    task(logger)
    sleep 2
  end
  show_message 'Finish Daemon'
end

my_task() だけを渡して、簡単に 上の2点を達成できるようなメソッド 、モジュールの形にするには
どうしたよいだろう?
既にそのようなものは存在していないのだろうか?

3
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?