Esempio n. 1
0
 def __on_receive_rpc_request(self, ch, method, props, body):
     self._logger.debug("received RPC req from exchange '%s' with routing key %s and correlation_id %s",
                        method.exchange, method.routing_key, props.correlation_id)
     
     # the following frames are handled here:
     # • RPC request messages
     #      - sent to empty exchange
     #      - routing_key is queue provided in _register_rpc_function
     
     # sanity check
     assert method.routing_key in self.__rpc_queue_map, \
         "%s not a valid RPC queue" % (method.routing_key,)
     
     # hand off the RPC request to the RPCWorker
     req_body = serializer_utils.deserialize(body, props.content_type)
     
     callback = None
     if req_body['command'] in self.__rpc_queue_map[method.routing_key]:
         callback = self.__rpc_queue_map[method.routing_key][req_body['command']]
         
         self.__rpc_worker.add_request(
             RPCRequest(
                 correlation_id = props.correlation_id,
                 content_type = props.content_type,
                 reply_to = props.reply_to,
                 callback = callback,
                 args = req_body['args']
             )
         )
     else:
         self._logger.error("command %s not configured for queue %s", req_body['command'], method.routing_key)
     
     ch.basic_ack(delivery_tag = method.delivery_tag)
Esempio n. 2
0
    def __on_receive_packet(self, ch, method, props, body):
        self._logger.debug("received packet from exchange '%s' with routing key %s and correlation_id %s",
                           method.exchange, method.routing_key, props.correlation_id)

        frame = serializer_utils.deserialize(body, props.content_type)
        
        # the following frames are handled here:
        #  • XBee "raw" frames
        #      - sent to exhange 'raw_xbee_frames'
        #      - routing_key is '<frame type>.<source addr>'
        #  • XBee reply frames in response to a command or data sent to a device
        #      - sent to empty exchange
        #      - routing_key is name of our private queue
        #      - have correlation_id matching a key in __pending_xb_requests
        
        # differentiate replies from raw packets
        if (props.correlation_id != None) and (method.routing_key == self.__queue_name):
            # this is a reply
            with self.__pending_xb_requests_lock:
                if props.correlation_id in self.__pending_xb_requests:
                    req = self.__pending_xb_requests[props.correlation_id]
                    
                    if not req.async:
                        self.finish_async_request(req, frame)
                    else:
                        self.handle_async_reply(req, frame)
                    
                else:
                    self._logger.error("got %s reply for unknown correlation %s: %s",
                                       frame['id'], props.correlation_id, frame)
            
            # this needs to get called every now and then
            self.__reap_unfinished_requests()
            
        else:
            # standard raw packet; guaranteed  to have a routing_key of the form
            # <frame id>.<address>, where the address is one we're subscribed to
            formatted_addr = method.routing_key.split('.')[1]
            
            try:
                self.handle_packet(formatted_addr, frame)
            except:
                self._logger.critical("exception handling packet", exc_info = True)
Esempio n. 3
0
    def __on_receive_rpc_response(self, channel, method, props, body):
        # props.correlation_id is the request ticket
        with self.__pending_requests_lock:
            request = self.__pending_requests.pop(props.correlation_id)

        try:
            resp_data = serializer_utils.deserialize(body, props.content_type)

            if "exception" in resp_data:
                request.exception = resp_data["exception"]
            else:
                request.response = resp_data["result"]
        except:
            self._logger.error("exception unpickling", exc_info=True)
            request.exception = sys.exc_info()[1]

        request.event.set()

        channel.basic_ack(delivery_tag=method.delivery_tag)
Esempio n. 4
0
 def __handle_xb_tx(self, chan, method, props, body):
     ## no need for a connection lock since we're running in the main
     ## thread, and there isn't any possibility for concurrent access
     ## to the connection for this thread
     
     try:
         # ack the message; there's nothing below that would be 
         # recoverable if the same message were received again
         chan.basic_ack(delivery_tag = method.delivery_tag)
         
         req = serializer_utils.deserialize(body, props.content_type)
         
         self._logger.debug(
             "TX method %s for dest %s with correlation ID %s",
             req['method'], req['dest'], props.correlation_id
         )
         
         # mapping of frame id to message properties; used to direct the
         # response
         frame_id = self.__next_frame_id()
         
         if props.headers == None:
             props.headers = {}
         
         if 'keep_alive' not in props.headers:
             props.headers['keep_alive'] = False
         
         with self.__correlation_lock:
             self.__correlations[frame_id] = {
                 'props' : props,
                 'keep_alive' : bool(props.headers['keep_alive']),
                 'expiration' : time.time() + 120,
             }
         
         if req['method'] == 'send_remote_at':
             # {'method' : 'send_remote_at',
             #  'dest' : <addr>,
             #  'command' : …,
             #  'param_val' : …,
             # }
             self.xbee.remote_at(frame_id = frame_id,
                                 dest_addr_long = parse_addr(req['dest']),
                                 command = req['command'],
                                 parameter = req['param_val'])
             
         
         elif req['method'] == 'send_data':
             # {'method' : 'send_data',
             #  'dest' : <addr>,
             #  'data' : …,
             # }
             self.xbee.zb_tx_request(
                 frame_id = frame_id,
                 dest_addr_long = parse_addr(req['dest']),
                 data = req['data']
             )
             
         
         self._logger.debug("XBee command sent and message ack'd")
         
     except:
         self._logger.error("failed processing XBee TX message",
                            exc_info = True)