Skip to content

Instantly share code, notes, and snippets.

@sapslaj
Last active March 3, 2016 01:27
Show Gist options
  • Select an option

  • Save sapslaj/acc1b9c40ba4d944b059 to your computer and use it in GitHub Desktop.

Select an option

Save sapslaj/acc1b9c40ba4d944b059 to your computer and use it in GitHub Desktop.
Daemonss.
class Daemon
def self.run!(options = {}, &block)
new(options, &block).run!
end
def initialize(options = {}, &block)
check_pid
daemonize
write_pid
trap_signals
redirect_output
@logfile = options[:logfile]
@pidfile = options[:pidfile]
@block = block
end
def logfile
@logfile || 'log/{$PROGRAM_NAME}.log'
end
def pidfile
@pidfile || 'log/pid/{$PROGRAM_NAME}.pid'
end
def run!
@block.call
end
def daemonize
exit if fork
Process.setsid
exit if fork
end
def redirect_output
FileUtils.mkdir_p(File.dirname(logfile), mode: 0755)
FileUtils.touch logfile
File.chmod(0644, logfile)
$stderr.reopen(logfile, 'a')
$stdout.reopen($stderr)
$stdout.sync = $stderr.sync = true
end
def suppress_output
$stderr.reopen('/dev/null', 'a')
$stdout.reopen($stderr)
end
def write_pid
FileUtils.mkdir_p(File.dirname(pidfile), mode: 0755)
File.open(pidfile, ::File::CREAT | ::File::EXCL | ::File::WRONLY) do |f|
f.write(Process.pid.to_s)
end
at_exit do
File.delete(pidfile) if File.exist?(pidfile)
end
rescue Errno::EEXIST
check_pid
retry
end
def check_pid
case pid_status(pidfile)
when :running, :not_owned
puts "A server is already running. Check #{pidfile}"
exit(1)
when :dead
File.delete(pidfile)
end
end
def pid_status(pidfile)
return :exited unless File.exist?(pidfile)
pid = ::File.read(pidfile).to_i
return :dead if pid == 0
Process.kill(0, pid)
:running
rescue Errno::ESRCH
:dead
rescue Errno::EPERM
:not_owned
end
def trap_signals
trap(:QUIT) do
exit
end
end
end
require "sinatra/base"
require "daemonss"
class App < Sinatra::Base
get "/" do
"I'm a daemon!"
end
end
Daemon.run! do
App.run!
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment