From: Jonathan Paisley Date: 2006-03-23T21:34:51+09:00 Subject: Re: drb over pipes On Thu, 23 Mar 2006 18:42:49 +0900, Reto Schuettel 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