Created
December 6, 2015 09:40
-
-
Save hx/27be61689e09a82c7adb to your computer and use it in GitHub Desktop.
Ruby Daemons with DRb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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