On Thu, 23 Mar 2006 18:42:49 +0900, Reto S. wrote:
I’d like to establish a drb connection over ssh, preferably over the
stdin/stdout channels which are provided by ssh itself. Is there a
drb protocol which uses pipes? If not, is it easy to implement?
I’ve seen that the tcpprotocol uses two connections, this could be
problem, as pipes/stdin/stdout only provide one stream.
At the end of the day I’d like to do something like that:
ruby client.rb | ssh host ‘ruby agent.rb’
I implemented a quick hack to do this. Hopefully the code below will
help.
It’s a bit of a mess, but allows you to use a DRb scheme like
‘drbfd://0,1’ which means uses file descriptors 0 and 1 (stdin/stdout)
for
communication.
module DRb
class DRbFDSocket
def self.parse_uri(uri)
if /^drbfd://(\d+),(\d+)(?:?(.*))?$/ =~ uri
[$1.to_i,$2.to_i, $3]
else
raise DRbBadScheme,uri unless uri =~ /^drbfd:/
raise DRbBadURI, "can’t parse uri: " + uri
end
end
def self.uri_option(uri,config)
infd,outfd, option = parse_uri(uri)
return ["drbfd://#{infd},#{outfd}", option]
end
def self.open(uri,config)
opts = parse_uri(uri)
self.new(uri,opts,config)
end
def self.open_server(uri,config)
opts = parse_uri(uri)
self.new(uri,opts,config)
end
def initialize(uri,fds,config)
@uri = uri
@in_fp = IO.new(fds[0],"r")
@out_fp = IO.new(fds[1],"w")
@out_fp.sync = true
@msg = DRbMessage.new(config)
end
attr_reader :uri
def send_request(ref, msg_id, arg, b)
begin
result = @msg.send_request(@out_fp, ref, msg_id, arg, b)
rescue DRb::DRbConnError
Kernel.exit! 0
end
result
end
def recv_request
begin
result = @msg.recv_request(@in_fp)
rescue DRb::DRbConnError
Kernel.exit! 0
end
result
end
def send_reply(succ, result)
begin
result = @msg.send_reply(@out_fp, succ, result)
rescue DRb::DRbConnError
Kernel.exit! 0
end
result
end
def recv_reply
begin
@msg.recv_reply(@in_fp)
rescue DRb::DRbConnError
Kernel.exit! 0
end
end
def alive?
true
end
def close
@in_fp.close
@out_fp.close
end
def accept
if @accepted then
sleep 60 while true
else
@accepted = true
self
end
end
end
DRbProtocol.add_protocol(DRbFDSocket)
end