class EmFarcall::Endpoint
Endpoint
that run in the reactor thread of the EM. Eventmachine should run by the time of creation of the endpoint. All the methods can be called from any thread, not only EM's reactor thread.
As the eventmachine callback paradigm is completely different from the threaded paradigm of the Farcall
, that runs pretty well under JRuby and in multithreaded MRI, we provide compatible but different endpoint to run under EM.
Its main difference is that there is no sync_call, instead, calling remote commands from the endpoint and/ot interface can provide blocks that are called when the remote is executed.
The EM version of the endpoint works with any 2 EM:C:Channels.
Attributes
Set or get provider instance. When provider is set, its public methods are called by the remote and any possible exception are passed back to caller party. You can use any ruby class instance everything will work, operators, indexes[] and like.
Public Class Methods
Create new endpoint to work with input and output channels
@param [EM::Channel] input_channel @param [EM::Channel] output_channel
# File lib/farcall/em_farcall.rb, line 40 def initialize(input_channel, output_channel, errback=nil, provider: nil) EM.schedule { @input, @output, @errback = input_channel, output_channel, errback @trace = false @in_serial = @out_serial = 0 @callbacks = {} @handlers = {} @unnamed_handler = -> (name, *args, **kwargs) { raise NoMethodError, "method does not exist: #{name}" } @input.subscribe { |data| process_input(data) } if provider @provider = provider provider.endpoint = self end } end
Public Instance Methods
Call the remote method with specified name and arguments calling block when done. Returns immediately a {Farcall::Promise} instance which could be used to control remote procedure invocation result asynchronously and effective.
Also, if block is provided, it will be called when the remote will be called and possibly return some data. It receives single object paramter with two fields: result.error and result.result. It is also possible to use returned {Farcall::Promise} instance to set multiple callbacks with ease. Promise callbacks are called after the block.
`result.error` is not nil when the remote raised error, then `error` and `error.text` are set accordingly.
if error is nil then result.result receives any return data from the remote method.
for example:
endpoint.call( 'some_func', 10, 20) { |done| if done.error puts "Remote error class: #{done.error[:class]}: #{done.error.text}" else puts "Remote returned #{done.result}" }
@param name [String] remote method name @return [Promise] object that call be used to set multiple handlers on success
or fail event. {Farcall::Promise#success} receives remote return result on success and {Farcall::Promise#fail} receives error object.
# File lib/farcall/em_farcall.rb, line 92 def call(name, *args, **kwargs, &block) promise = Farcall::Promise.new EM.schedule { @callbacks[@in_serial] = -> (result) { block.call(result) if block != nil if result.error promise.set_fail result.error else promise.set_success result.result end } send_block cmd: name, args: args, kwargs: kwargs } promise end
Close the endpoint
# File lib/farcall/em_farcall.rb, line 109 def close super end
Report error via errback and the endpoint
# File lib/farcall/em_farcall.rb, line 114 def error text STDERR.puts "farcall ws server error #{text}" EM.schedule { @errback.call(text) if @errback close } end
Set handler to perform the named command. Block will be called when the remote party calls with parameters passed from the remote. The block returned value will be passed back to the caller.
If the block raises the exception it will be reported to the caller as an error (depending on it's platofrm, will raise exception on its end or report error)
# File lib/farcall/em_farcall.rb, line 128 def on(name, &block) @handlers[name.to_s] = block end
Process remote command. First parameter passed to the block is the method name, the rest are optional arguments of the call:
endpoint.on_command { |name, *args, **kwargs| if name == 'echo' { args: args, keyword_args: kwargs } else raise "unknown command" end }
raising exceptions from the block cause farcall error to be returned back th the caller.
# File lib/farcall/em_farcall.rb, line 144 def on_command &block raise "unnamed handler should be present" unless block @unnamed_handler = block end
Same as on_command
(compatibilty method)
# File lib/farcall/em_farcall.rb, line 150 def on_remote_call &block on_command &block end
Get the Farcall::RemoteInterface connnected to this endpoint. Any subsequent calls with return the same instance.
# File lib/farcall/em_farcall.rb, line 156 def remote @remote ||= EmFarcall::Interface.new endpoint: self end