30 Days of Tech: Day 24 - drubyall
June 24th, 2008
When we first started trying to use distributed DeepTest, we quickly ran into an issue with DRb servers not binding to the correct addresses. DRb does provide a way to bind to 0.0.0.0 to listen to all addresses, but there’s a downside to the way it does it. The url you provide to DRb to accomplish this must omit the hostname (e.g. druby://:0/). DRb then determines what hostname to report to clients by calling getaddrinfo with the empty hostname. Unfortunately for us getaddrinfo didn’t provide a hostname that could be used by our developer machines to connect to the DeepTest servers. For a brief moment we thought we were stuck.
When we looked into how DRb handles protocols, however, we realized we could simply add a protocol that would accept a hostname as part of the url and use it to report the DRb url to clients when needed. For listening on the network, however, the protocol always binds to 0.0.0.0. By registering this protocol (which we called drubyall since it listens on all interfaces) you can use it in any DRb url, which is pretty handy. Although it wasn’t nice that we ran into the problem, it was very nice that DRb gave us an easy out to extending its communications layer.
module DeepTest
class DRbBindAllTCPSocket < DRb::DRbTCPSocket
def self.parse_uri(uri)
if uri =~ /^drubyall:\/\/(.*?):(\d+)(\?(.*))?$/
host = $1
port = $2.to_i
option = $4
[host, port, option]
else
raise(DRb::DRbBadScheme, uri) unless uri =~ /^drubyall:/
raise(DRb::DRbBadURI, 'can\'t parse uri:' + uri)
end
end
# Open a server listening for connections at +uri+ using
# configuration +config+.
def self.open_server(uri, config)
uri = 'drubyall://:0' unless uri
host, port, opt = parse_uri(uri)
if host.size == 0
host = getservername
end
DeepTest.logger.debug("Listening on port #{port}, all addresses.")
soc = TCPServer.open('0.0.0.0', port)
port = soc.addr[1] if port == 0
uri = "druby://#{host}:#{port}"
self.new(uri, soc, config)
end
end
end
DRb::DRbProtocol.add_protocol DeepTest::DRbBindAllTCPSocket
Sorry, comments are closed for this article.