Module: Thin::Daemonizable

Module Thin::Daemonizable < Base

(in files lib/thin/daemonizing.rb )

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

Methods

Public Class included(base)

    # File lib/thin/daemonizing.rb, line 27
27:     def self.included(base)
28:       base.extend ClassMethods
29:     end

Public Instance change_privilege(user, group=user)

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

    # File lib/thin/daemonizing.rb, line 59
59:     def change_privilege(user, group=user)
60:       log ">> Changing process privilege to #{user}:#{group}"
61:       
62:       uid, gid = Process.euid, Process.egid
63:       target_uid = Etc.getpwnam(user).uid
64:       target_gid = Etc.getgrnam(group).gid
65: 
66:       if uid != target_uid || gid != target_gid
67:         # Change process ownership
68:         Process.initgroups(user, target_gid)
69:         Process::GID.change_privilege(target_gid)
70:         Process::UID.change_privilege(target_uid)
71:       end
72:     rescue Errno::EPERM => e
73:       log "Couldn't change user and group to #{user}:#{group}: #{e}"
74:     end

Public Instance daemonize()

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

    # File lib/thin/daemonizing.rb, line 36
36:     def daemonize
37:       raise PlatformNotSupported, 'Daemonizing is not supported on Windows'     if Thin.win?
38:       raise ArgumentError,        'You must specify a pid_file to daemonize' unless @pid_file
39: 
40:       remove_stale_pid_file
41:       
42:       pwd = Dir.pwd # Current directory is changed during daemonization, so store it
43:       
44:       Daemonize.daemonize(File.expand_path(@log_file), name)
45:       
46:       Dir.chdir(pwd)
47:       
48:       write_pid_file
49:       
50:       trap('HUP') { restart }
51:       at_exit do
52:         log ">> Exiting!"
53:         remove_pid_file
54:       end
55:     end

Public Instance on_restart(&block)

Register a proc to be called to restart the server.

    # File lib/thin/daemonizing.rb, line 77
77:     def on_restart(&block)
78:       @on_restart = block
79:     end

Public Instance pid()

    # File lib/thin/daemonizing.rb, line 31
31:     def pid
32:       File.exist?(pid_file) ? open(pid_file).read.to_i : nil
33:     end

Public Instance restart()

Restart the server.

    # File lib/thin/daemonizing.rb, line 82
82:     def restart
83:       raise ArgumentError, "Can't restart, no 'on_restart' proc specified" unless @on_restart
84:       log '>> Restarting ...'
85:       stop
86:       remove_pid_file
87:       @on_restart.call
88:       exit!
89:     end

Protected Instance remove_pid_file()

     # File lib/thin/daemonizing.rb, line 150
150:       def remove_pid_file
151:         File.delete(@pid_file) if @pid_file && File.exists?(@pid_file)
152:       end

Protected Instance remove_stale_pid_file()

If PID file is stale, remove it.

     # File lib/thin/daemonizing.rb, line 162
162:       def remove_stale_pid_file
163:         if File.exist?(@pid_file)
164:           if pid && Process.running?(pid)
165:             raise PidFileExist, "#{@pid_file} already exists, seems like it's already running (process ID: #{pid}). " +
166:                                 "Stop the process or delete #{@pid_file}."
167:           else
168:             log ">> Deleting stale PID file #{@pid_file}"
169:             remove_pid_file
170:           end
171:         end
172:       end

Protected Instance write_pid_file()

     # File lib/thin/daemonizing.rb, line 154
154:       def write_pid_file
155:         log ">> Writing PID to #{@pid_file}"
156:         FileUtils.mkdir_p File.dirname(@pid_file)
157:         open(@pid_file,"w") { |f| f.write(Process.pid) }
158:         File.chmod(0644, @pid_file)
159:       end