Class: Simrpc::MethodMessageController

Inherits:
Object
  • Object
show all
Defined in:
lib/simrpc.rb

Overview

Simrpc Method Message Controller, generates and handles method messages

Instance Method Summary collapse

Constructor Details

#initialize(schema_def) ⇒ MethodMessageController

initialize with a specified schema definition



659
660
661
# File 'lib/simrpc.rb', line 659

def initialize(schema_def)
  @schema_def = schema_def
end

Instance Method Details

#generate(method_name, args) ⇒ Object

generate new new method message, setting the message target to the specified method name, and setting the fields on the message to the method arguments



666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
# File 'lib/simrpc.rb', line 666

def generate(method_name, args)
   @schema_def.methods.each { |method|
     if method.name == method_name
       msg = Message::Message.new
       msg.header.type = 'request'
       msg.header.target = method.name

       # loop through each param, convering corresponding
       # argument to message field and adding it to msg
       i = 0
       method.parameters.each { |param|
         field = Message::Field.new
         field.name = param.name
         field.value = param.to_s(args[i], @schema_def)
         msg.body.fields.push field
         i += 1
       }

       return msg
     end
   }
   return nil
end

#message_received(node, message, reply_to) ⇒ Object

should be invoked when a message is received, takes a message, converts it into a method call, and calls the corresponding handler in the provided schema. Takes return arguments and sends back to caller



693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
# File 'lib/simrpc.rb', line 693

def message_received(node, message, reply_to)
   message = Message::Message::from_s(message)
   @schema_def.methods.each { |method|

     if method.name == message.header.target
       Logger.info "received method #{method.name} message "

       # for request messages, dispatch to method handler
       if message.header.type != 'response' && method.handler != nil
           # order the params
           params = []
           method.parameters.each { |data_field|
             value_field = message.body.fields.find { |f| f.name == data_field.name }
             params.push data_field.from_s(value_field.value, @schema_def) unless value_field.nil? # TODO what if value_field is nil
           }

           Logger.info "invoking #{method.name} handler "

           # invoke method handler
           return_values = method.handler.call(*params)  # FIXME handlers can't use 'return' as this will fall through here
                                                         # FIXME throw a catch block around this call to catch all handler exceptions
           return_values = [return_values] unless return_values.is_a? Array

           # if method returns no values, do not return response
           unless method.return_values.size == 0

              # consruct and send response message using return values
              response = Message::Message.new
              response.header.type = 'response'
              response.header.target = method.name
              (0...method.return_values.size).each { |rvi|
                field = Message::Field.new
                field.name = method.return_values[rvi].name
                field_def = method.return_values.find { |rv| rv.name == field.name }
                field.value = field_def.to_s(return_values[rvi], @schema_def) unless field_def.nil? # TODO what if field_def is nil
                response.body.fields.push field
              }
              Logger.info "responding to #{reply_to}"
              node.send_message(reply_to, response)

           end

       # for response values just return converted return values
       else
           results = []
           method.return_values.each { |data_field|
             value_field = message.body.fields.find { |f| f.name == data_field.name }
             results.push data_field.from_s(value_field.value, @schema_def) unless value_field.nil? # TODO what if value_field is nil
           }
           return results
       end
     end
   }
end