class Process::Daemon

Provides the infrastructure for spawning a daemon.

Constants

TIMEOUT

Daemon startup timeout

VERSION

Attributes

title[R]

The process title of the daemon.

working_directory[R]

The directory the daemon will run in.

Public Class Methods

controller(options = {}) click to toggle source

The process controller, responsible for managing the daemon process start, stop, restart, etc.

# File lib/process/daemon.rb, line 172
def controller(options = {})
        @controller ||= Controller.new(instance, options)
end
daemonize(*args, **options) click to toggle source

The main entry point for daemonized scripts.

# File lib/process/daemon.rb, line 177
def daemonize(*args, **options)
        args = ARGV if args.empty?
        
        controller(options).daemonize(args)
end
instance() click to toggle source

A shared instance of the daemon.

# File lib/process/daemon.rb, line 167
def instance
        @instance ||= self.new
end
new(working_directory = ".") click to toggle source

Initialize the daemon in the given working root.

# File lib/process/daemon.rb, line 34
def initialize(working_directory = ".")
        @working_directory = working_directory
        
        @shutdown_notification = Notification.new
end
start() click to toggle source

Start the shared daemon instance.

# File lib/process/daemon.rb, line 184
def start
        controller.start
end
status() click to toggle source

Check if the shared daemon instance is runnning or not.

# File lib/process/daemon.rb, line 194
def status
        controller.status
end
stop() click to toggle source

Stop the shared daemon instance.

# File lib/process/daemon.rb, line 189
def stop
        controller.stop
end

Public Instance Methods

crashed?() click to toggle source

Check the last few lines of the log file to find out if the daemon crashed.

# File lib/process/daemon.rb, line 85
def crashed?
        count = 3
        
        LogFile.open(log_file_path).tail_log do |line|
                return true if line.match("=== Daemon Crashed")

                break if (count -= 1) == 0
        end

        return false
end
log_directory() click to toggle source

Return the directory to store log files in.

# File lib/process/daemon.rb, line 49
def log_directory
        File.join(working_directory, "log")
end
log_file_path() click to toggle source

Standard log file for stdout and stderr.

# File lib/process/daemon.rb, line 54
def log_file_path
        File.join(log_directory, "#{name}.log")
end
mark_log() click to toggle source

Mark the output log.

# File lib/process/daemon.rb, line 69
def mark_log
        File.open(log_file_path, "a") do |log_file|
                log_file.puts "=== Log Marked @ #{Time.now.to_s} [#{Process.pid}] ==="
        end
end
name() click to toggle source

Return the name of the daemon

# File lib/process/daemon.rb, line 41
def name
        return self.class.name.gsub(/[^a-zA-Z0-9]+/, '-')
end
prefork() click to toggle source

The main function to setup any environment required by the daemon

# File lib/process/daemon.rb, line 98
def prefork
        # Ignore any previously setup signal handler for SIGINT:
        trap(:INT, :DEFAULT)
        
        # We update the working directory to a full path:
        @working_directory = File.expand_path(working_directory)
        
        FileUtils.mkdir_p(log_directory)
        FileUtils.mkdir_p(runtime_directory)
end
process_file_path() click to toggle source

Standard location of process pid file.

# File lib/process/daemon.rb, line 64
def process_file_path
        File.join(runtime_directory, "#{name}.pid")
end
request_shutdown() click to toggle source

Request that the sleep_until_interrupted function call returns.

# File lib/process/daemon.rb, line 124
def request_shutdown
        @shutdown_notification.signal
end
run() click to toggle source

If you want to implement a long running process you override this method. You may like to call super but it is not necessary to use the supplied interruption machinery.

# File lib/process/daemon.rb, line 142
def run
        sleep_until_interrupted
end
runtime_directory() click to toggle source

Runtime data directory for the daemon.

# File lib/process/daemon.rb, line 59
def runtime_directory
        File.join(working_directory, "run")
end
shutdown() click to toggle source

This function should terminate any active processes in the daemon and return as quickly as possible.

# File lib/process/daemon.rb, line 147
def shutdown
end
sleep_until_interrupted() click to toggle source

Call this function to sleep until the daemon is sent SIGINT.

# File lib/process/daemon.rb, line 129
def sleep_until_interrupted
        trap(:INT) do
                self.request_shutdown
        end

        @shutdown_notification.wait
end
spawn() click to toggle source

The entry point from the newly forked process.

# File lib/process/daemon.rb, line 151
def spawn
        self.title = self.name
        
        self.startup
        
        begin
                self.run
        rescue Interrupt
                $stderr.puts "Daemon interrupted, proceeding to shutdown."
        end
        
        self.shutdown
end
startup() click to toggle source

This function must setup the daemon quickly and return.

# File lib/process/daemon.rb, line 138
def startup
end
tail_log(output) click to toggle source

Prints some information relating to daemon startup problems.

# File lib/process/daemon.rb, line 76
def tail_log(output)
        lines = LogFile.open(log_file_path).tail_log do |line|
                line.match("=== Log Marked") || line.match("=== Daemon Exception Backtrace")
        end
        
        output.puts lines
end
title=(title) click to toggle source

Set the process title - only works after daemon has forked.

# File lib/process/daemon.rb, line 113
def title= title
        @title = title
        
        if Process.respond_to? :setproctitle
                Process.setproctitle(@title)
        else
                $0 = @title
        end
end