Class: MarilynRPC::NativeClient
- Inherits:
-
Object
- Object
- MarilynRPC::NativeClient
- Defined in:
- lib/marilyn-rpc/client.rb
Overview
The client that will handle the socket to the remote. The native client is written in pure ruby.
Constant Summary collapse
- MAIL_KEY =
:_mlynml
Class Method Summary collapse
-
.connect_tcp(host, port, options = {}) ⇒ MarilynRPC::NativeClient
Connect to a tcp socket.
-
.connect_unix(path) ⇒ MarilynRPC::NativeClient
Connect to a unix domain socket.
Instance Method Summary collapse
-
#authenticate(username, password, method = :plain) ⇒ Object
authenicate the client to call methods that require authentication.
-
#disconnect ⇒ Object
Disconnect the client from the remote.
-
#execute(path, method, args) ⇒ Object
private
Executes a client call blocking.
-
#for(path) ⇒ MarilynRPC::NativeClientProxy
Creates a new Proxy Object for the connection.
-
#initialize(socket) ⇒ NativeClient
constructor
Create a native client for the socket.
Constructor Details
#initialize(socket) ⇒ NativeClient
Create a native client for the socket.
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/marilyn-rpc/client.rb', line 39 def initialize(socket) @socket = socket @semaphore = Mutex.new @threads = {} @thread = Thread.new do # read the answer of the server back in envelope = MarilynRPC::Envelope.new loop do # read the header to have the size envelope.parse_header! @socket.read(MarilynRPC::Envelope::HEADER_SIZE) # so now that we know the site, read the rest of the envelope without # parsing envelope.content = @socket.read(envelope.size) # returns the result part of the mail or raise the exception if there is # one mail = MarilynRPC::MailFactory.unpack(envelope) thread = @semaphore.synchronize { @threads.delete(mail.tag) } thread[MAIL_KEY] = mail # save the mail for the waiting thread thread.wakeup # wake up the waiting thread envelope.reset! end end end |
Class Method Details
.connect_tcp(host, port, options = {}) ⇒ MarilynRPC::NativeClient
Connect to a tcp socket.
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
# File 'lib/marilyn-rpc/client.rb', line 105 def self.connect_tcp(host, port, = {}) if [:secure] == true require 'openssl' # use openssl for secure connections socket = TCPSocket.new(host, port) if ssl_context = [:ssl_context] secure_socket = OpenSSL::SSL::SSLSocket.new(socket, ssl_context) else secure_socket = OpenSSL::SSL::SSLSocket.new(socket) end secure_socket.connect new(secure_socket) else new(TCPSocket.open(host, port)) end end |
.connect_unix(path) ⇒ MarilynRPC::NativeClient
Connect to a unix domain socket.
91 92 93 |
# File 'lib/marilyn-rpc/client.rb', line 91 def self.connect_unix(path) new(UNIXSocket.new(path)) end |
Instance Method Details
#authenticate(username, password, method = :plain) ⇒ Object
authenicate the client to call methods that require authentication
74 75 76 77 |
# File 'lib/marilyn-rpc/client.rb', line 74 def authenticate(username, password, method = :plain) execute(MarilynRPC::Service::AUTHENTICATION_PATH, "authenticate_#{method}".to_sym, [username, password]) end |
#disconnect ⇒ Object
Disconnect the client from the remote.
65 66 67 |
# File 'lib/marilyn-rpc/client.rb', line 65 def disconnect @socket.close end |
#execute(path, method, args) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Executes a client call blocking. To issue an async call one needs to have start separate threads. THe Native client uses then multiplexing to avoid the other threads blocking.
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 |
# File 'lib/marilyn-rpc/client.rb', line 130 def execute(path, method, args) thread = Thread.current tag = "#{Time.now.to_f}:#{thread.object_id}" @semaphore.synchronize { # since this client can't multiplex, we set the tag to nil @socket.write(MarilynRPC::MailFactory.build_call(tag, path, method, args)) # lets write our self to the list of waining threads @threads[tag] = thread } # stop the current thread, the thread will be started after the response # arrived Thread.stop # get mail from responses mail = thread[MAIL_KEY] if mail.is_a? MarilynRPC::CallResponseMail mail.result else raise MarilynError.new # raise exception to capture the client backtrace end rescue MarilynError => exception # add local and remote trace together and reraise the original exception backtrace = [] backtrace += exception.backtrace backtrace += mail.exception.backtrace mail.exception.set_backtrace(backtrace) raise mail.exception end |
#for(path) ⇒ MarilynRPC::NativeClientProxy
Creates a new Proxy Object for the connection.
84 85 86 |
# File 'lib/marilyn-rpc/client.rb', line 84 def for(path) NativeClientProxy.new(path, self) end |