class Protobuf::Rpc::Service

def call_rpc(method, pb_request)


server is setup to handle synchronous and asynchronous responses.
by calling self.send_response without any arguments. The rpc
the responsibility of the service method to send the response,
by explicitly setting self.async_responder = true. It is then
Async behavior of responding can be achieved in the rpc method

a normal (http-based) controller method would be able to.
as there is no way to reliably determine the response like
that response should be manipulated during the rpc method,
that request and response are implicitly available, and
Implementing rpc methods should be aware

and response instances.
before and after behavior, most notably setting up the request
call_rpc allows us to wrap the normal method call with
Call the rpc method that was previously privatized.
def call_rpc(method, pb_request)
  @current_method = method
  
  # Allows the service to set whether or not
  # it would like to asynchronously respond to the connected client(s)
  @async_responder = false
  
  # Setup the request
  @request = rpcs[method].request_type.new
  @request.parse_from_string(pb_request.request_proto)
rescue
  exc = BadRequestProto.new 'Unable to parse request: %s' % $!.message
  log_error exc.message
  log_error $!.backtrace.join("\n")
  raise exc
else   # when no Exception was thrown
  # Setup the response
  @response = rpcs[method].response_type.new
  log_debug "[#{log_signature}] calling service method %s#%s" % [self.class, method]
  # Call the aliased rpc method (e.g. :rpc_find for :find)
  __send__("rpc_#{method}".to_sym)
  log_debug "[#{log_signature}] completed service method %s#%s" % [self.class, method]
  
  # Pass the populated response back to the server
  # Note this will only get called if the rpc method didn't explode (by design)
  if @async_responder
    log_debug "[#{log_signature}] async request, not sending response (yet)"
  else
    log_debug "[#{log_signature}] trigger server send_response"
    send_response
  end
end