Class: DRb::DRbSSHRemoteClient

Inherits:
DRbSSHClient show all
Defined in:
lib/drbssh.rb

Overview

DRbSSH remote client - does the heavy lifting of SSH’ing to a remote server and bootstrapping its Ruby interpreter for DRb communication.

Instance Attribute Summary

Attributes inherited from DRbSSHClient

#read_fd, #receiveq, #sendq, #write_fd

Instance Method Summary collapse

Methods inherited from DRbSSHClient

#alive?, #recv_reply, #send_request

Constructor Details

#initialize(uri, server) ⇒ DRbSSHRemoteClient

Create an SSH-connection to uri, and spawn a server, so client has something to talk to



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/drbssh.rb', line 93

def initialize(uri, server)
	# child-to-parent, parent-to-child
	ctp_rd, ctp_wr = IO.pipe
	ptc_rd, ptc_wr = IO.pipe

	host, cmd = DRbSSHProtocol.split_uri(uri)

	# Read the source-code for this file, and add bits for initialising the remote side.
	# Since DRbSSHServer is doing all the filedescriptor read/writing, we need to start
	# a DRbSSHLocalClient immediately.
	self_code = <<-EOT
		#{File.read(__FILE__)};
		DRb.start_service("#{uri}", binding)
		DRb.thread['DRbSSHLocalClient'] = DRb::DRbSSHLocalClient.new(DRb::DRbSSHProtocol.server)
		DRb.thread.join
	EOT

	# Fork to create an SSH child-process
	if fork.nil?
		# In child - cleanup filehandles, reopen stdin/stdout, and exec ssh to connect to remote

		ctp_rd.close
		ptc_wr.close

		$stdin.reopen(ptc_rd)
		$stdout.reopen(ctp_wr)

		cmd = ['ruby'] if cmd.nil? or cmd.empty?

		# exec Ruby on remote end, and read bootstrap code.
		exec("ssh", "-oBatchMode=yes", "-T", host, "exec", *cmd, '-e', "\"eval STDIN.read(#{self_code.bytesize})\"")
		exit
	else
		# In parent - cleanup filehandles, write bootstrap-code, and hand over to superclass.

		ctp_wr.close
		ptc_rd.close

		# Bootstrap remote Ruby.
		ptc_wr.write(self_code)

		@read_fd, @write_fd = ctp_rd, ptc_wr

		super(server)
	end
end

Instance Method Details

#closeObject

Close client.



141
142
143
144
145
146
# File 'lib/drbssh.rb', line 141

def close
	# Closing the filedescriptors should trigger an IOError in the server-thread
	# waiting, which makes it close the client attached.
	self.read_fd.close unless self.read_fd.closed?
	self.write_fd.close unless self.write_fd.closed?
end