Module: Daemonizable

Included in:
Bluth::ScheduleWorker, Bluth::Worker
Defined in:
lib/daemonizing.rb

Overview

Module included in classes that can be turned into a daemon. Handle stuff like:

  • storing the PID in a file

  • redirecting output to the log file

  • changing processs privileges

  • killing the process gracefully

Defined Under Namespace

Modules: ClassMethods

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#log_fileObject

Returns the value of attribute log_file.



24
25
26
# File 'lib/daemonizing.rb', line 24

def log_file
  @log_file
end

#pid_fileObject

Returns the value of attribute pid_file.



24
25
26
# File 'lib/daemonizing.rb', line 24

def pid_file
  @pid_file
end

Class Method Details

.included(base) ⇒ Object



26
27
28
# File 'lib/daemonizing.rb', line 26

def self.included(base)
  base.extend ClassMethods
end

Instance Method Details

#change_privilege(user, group = user) ⇒ Object

Change privileges of the process to the specified user and group.



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/daemonizing.rb', line 60

def change_privilege(user, group=user)
  log ">> Changing process privilege to #{user}:#{group}"
  
  uid, gid = Process.euid, Process.egid
  target_uid = Etc.getpwnam(user).uid
  target_gid = Etc.getgrnam(group).gid

  if uid != target_uid || gid != target_gid
    # Change process ownership
    Process.initgroups(user, target_gid)
    Process::GID.change_privilege(target_gid)
    Process::UID.change_privilege(target_uid)
  end
rescue Errno::EPERM => e
  log "Couldn't change user and group to #{user}:#{group}: #{e}"
end

#daemonizeObject

Turns the current script into a daemon process that detaches from the console.

Raises:

  • (ArgumentError)


35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/daemonizing.rb', line 35

def daemonize
  raise ArgumentError,        'You must specify a pid_file to daemonize' unless @pid_file
  
  remove_stale_pid_file
  
  pwd = Dir.pwd # Current directory is changed during daemonization, so store it
  
  # HACK we need to create the directory before daemonization to prevent a bug under 1.9
  #      ignoring all signals when the directory is created after daemonization.
  FileUtils.mkdir_p File.dirname(@pid_file)
  
  Daemonize.daemonize(File.expand_path(@log_file), name)
  
  Dir.chdir(pwd)
  
  write_pid_file
  
  at_exit do
    log ">> Exiting!"
    remove_pid_file
  end
end

#on_restart(&block) ⇒ Object

Register a proc to be called to restart the server.



78
79
80
# File 'lib/daemonizing.rb', line 78

def on_restart(&block)
  @on_restart = block
end

#pidObject



30
31
32
# File 'lib/daemonizing.rb', line 30

def pid
  File.exist?(pid_file) ? open(pid_file).read.to_i : nil
end

#restartObject

Restart the server.



83
84
85
86
87
88
89
90
91
# File 'lib/daemonizing.rb', line 83

def restart
  if @on_restart
    log '>> Restarting ...'
    stop
    remove_pid_file
    @on_restart.call
    exit!
  end
end