Skip to content

Instantly share code, notes, and snippets.

@bastos
Created December 15, 2008 10:08
Show Gist options
  • Save bastos/35917 to your computer and use it in GitHub Desktop.
Save bastos/35917 to your computer and use it in GitHub Desktop.
require "rubygems"
require "dnssd"
require "set"
require "socket"
require "webrick"
module AliveJour
include Socket::Constants
Paste = Struct.new(:name, :host, :port)
SERVICE = "_mongrelintercon._tcp"
def self.list
servers = {}
service = DNSSD.browse(SERVICE) do |reply|
servers[reply.name] ||= reply
end
STDERR.puts "Searching for servers (3 seconds)"
# Wait for something to happen
sleep 3
service.stop
servers.each { |string,obj|
STDERR.puts "Found mongrels: '#{string}'"
}
end
def self.find(name, first=true)
hosts = Set.new
waiting = Thread.current
service = DNSSD.browse(SERVICE) do |reply|
if name === reply.name
DNSSD.resolve(reply.name, reply.type, reply.domain) do |rr|
hosts << Paste.new(reply.name, rr.target, rr.port)
waiting.run if first
end
end
end
sleep 5
service.stop
hosts
end
def self.get(name)
hosts = find(name)
if hosts.empty?
STDERR.puts "ERROR: Unable to find #{name}"
elsif hosts.size > 1
STDERR.puts "ERROR: Multiple possibles found:"
hosts.each do |host|
STDERR.puts " #{host.name} (#{host.host}:#{host.port})"
end
else
# Set is weird. There is no #[] or #at
hosts.each do |host|
STDERR.puts "(#{host.name} from #{host.host}:#{host.port})"
sock = TCPSocket.open host.host, host.port
return sock.read
end
end
end
def self.serve(name, multiple, contents, port)
tr = DNSSD::TextRecord.new
tr["description"] = "Im #{$$}."
DNSSD.register(name, SERVICE, "local", port, tr.encode) do |reply|
STDERR.puts "MONGREL ALIVE #{name} "
end
log = WEBrick::Log.new(true) # true fools it
def log.log(*anything); end # send it to the abyss
server = WEBrick::GenericServer.new(:Port => port, :Logger => log)
%w(INT TERM).each do |signal|
trap signal do
server.shutdown
exit!
end
end
server.start do |socket|
socket.print(contents)
server.shutdown unless multiple
end
end
end
=begin
if ARGV.first == "list"
AliveJour.list()
else
Thread.abort_on_exception = true
alivejour = Thread.new do
JOUR_PORT = "#{OPTIONS[:port]}0".to_i
AliveJour.serve("#{$$}:#{Time.now.to_f}:#{JOUR_PORT}", true, "OK", JOUR_PORT)
end
end
=end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment