Skip to content

Instantly share code, notes, and snippets.

@hx
Created December 6, 2015 09:40
Show Gist options
  • Save hx/27be61689e09a82c7adb to your computer and use it in GitHub Desktop.
Save hx/27be61689e09a82c7adb to your computer and use it in GitHub Desktop.
Ruby Daemons with DRb
require 'drb'
require 'pathname'
require 'shellwords'
require 'timeout'
module DRb
class Daemon
PATH_KEY = 'DRB_DAEMON_PATH'
PROTOCOL = 'drbunix:'
def start
if ENV.key? PATH_KEY
STDOUT.sync = true
STDERR.sync = true
server = DRb.start_service(PROTOCOL, yield)
data = {
uri: server.uri,
pid: $$
}
@path.open('w') { |f| f.write Marshal.dump data }
server.thread.join
@path.delete
exit
end
start_daemon unless @path.exist?
DRb.start_service(PROTOCOL)
Signal.trap 'INT' do
system "kill #{read_data[:pid]}"
raise Interrupt
end
connect_or_start
end
def initialize(path)
@path = Pathname(path)
end
private
def start_daemon
@path.parent.mkpath
@path.delete if @path.exist?
system "#{PATH_KEY}=#{e @path.to_s} nohup ruby #{[$0, *ARGV].shelljoin} >> #{e @path.to_s}.log 2>&1 &"
Timeout.timeout 5 do
loop do
return if @path.exist?
sleep 0.1
end
end
end
def connect_or_start
DRb::DRbObject.new_with_uri(uri).tap { |obj| obj.respond_to? :testing123 }
rescue DRb::DRbConnError
start_daemon
DRb::DRbObject.new_with_uri uri
end
def e(str)
Shellwords.escape str
end
def uri
@path.exist? ? read_data[:uri] : nil
end
def read_data
Marshal.load @path.read
end
end
def self.Daemon(path = nil, &block)
Daemon.new(path).start &block
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment