lib/rflow/daemon_process.rb in rflow-1.3.0 vs lib/rflow/daemon_process.rb in rflow-1.3.1
- old
+ new
@@ -1,17 +1,23 @@
require 'rflow/pid_file'
class RFlow
+ # Encapsulates a master process being managed by RFlow that can run in the foreground
+ # or daemonize.
class DaemonProcess
+ # Symbolic constant for SIGINFO as this is only defined on BSD and not in Ruby.
SIGINFO = 29
def initialize(name, role = name, options = {})
@name = name
@role = role
@pid_file = PIDFile.new(options[:pid_file_path]) if options[:pid_file_path]
end
+ # Daemonize by forking and exiting the parent after handling
+ # IO streams and checking successful start of the new copy.
+ # @return [void]
def daemonize!
RFlow.logger.info "#{@name} daemonizing"
establish_daemon_pipe
drop_database_connections
@@ -21,10 +27,15 @@
else
daemonize_process
end
end
+ # Execute the master process. Writes out a pidfile and updates the process
+ # name, installs signal handlers, and spawns all the defined subprocesses.
+ # Finally executes {run_process}; when that returns, it will
+ # exit with the resulting return code.
+ # @return [void]
def run!
write_pid_file
register_logging_context
update_process_name
handle_signals
@@ -36,12 +47,26 @@
ensure
unhandle_signals
remove_pid_file
end
+ # Default implementation. Subclasses should override to provide logic
+ # for actually spawning subprocesses.
+ # @return [void]
def spawn_subprocesses; end
+
+ # Default implementation. Subclasses should override to provide logic
+ # for actually doing something useful.
+ # @return [void]
+ def run_process; end
+
+ # A list of {ChildProcess}es to start and signal.
+ # @return [Array<ChildProcess>]
def subprocesses; []; end
+ # Shut down the application. Cleans up the pid file, removes
+ # signal handlers, and signals all child processes with +SIGQUIT+.
+ # @return [void]
def shutdown!(reason)
RFlow.logger.info "#{@name} shutting down due to #{reason}"
remove_pid_file
unhandle_signals
signal_subprocesses('QUIT')