示例#1
0
    def receive_loop(self, msgs_callback):
        """
        Receive messages until shutdown
        @param msgs_callback: callback to invoke for new messages received    
        @type  msgs_callback: fn([msg])
        """
        # - use assert here as this would be an internal error, aka bug
        logger.debug("receive_loop for [%s]", self.name)
        try:
            try:
                while not self.done and not is_shutdown():
                    msgs = self.receive_once()
                    if not self.done and not is_shutdown():
                        msgs_callback(msgs)

                rospydebug("receive_loop[%s]: done condition met, exited loop"%self.name)
            except DeserializationError as e:
                logerr("[%s] error deserializing incoming request: %s"%self.name, str(e))
                rospyerr("[%s] error deserializing incoming request: %s"%self.name, traceback.format_exc())                 
            except:
                # in many cases this will be a normal hangup, but log internally
                try:
                    #1467 sometimes we get exceptions due to
                    #interpreter shutdown, so blanket ignore those if
                    #the reporting fails
                    rospydebug("exception in receive loop for [%s], may be normal. Exception is %s",self.name, traceback.format_exc())                    
                except: pass
        finally:
            if not self.done:
                self.close()
示例#2
0
    def receive_loop(self, msgs_callback):
        """
        Receive messages until shutdown
        @param msgs_callback: callback to invoke for new messages received    
        @type  msgs_callback: fn([msg])
        """
        # - use assert here as this would be an internal error, aka bug
        logger.debug("receive_loop for [%s]", self.name)
        try:
            while not self.done and not is_shutdown():
                try:
                    if self.socket is not None:
                        msgs = self.receive_once()
                        if not self.done and not is_shutdown():
                            msgs_callback(msgs, self)
                    else:
                        self._reconnect()

                except TransportException as e:
                    # set socket to None so we reconnect
                    try:
                        if self.socket is not None:
                            try:
                                self.socket.shutdown()
                            except:
                                pass
                            finally:
                                self.socket.close()
                    except:
                        pass
                    self.socket = None

                except DeserializationError as e:
                    #TODO: how should we handle reconnect in this case?

                    logerr(
                        "[%s] error deserializing incoming request: %s" %
                        self.name, str(e))
                    rospyerr(
                        "[%s] error deserializing incoming request: %s" %
                        self.name, traceback.format_exc())
                except:
                    # in many cases this will be a normal hangup, but log internally
                    try:
                        #1467 sometimes we get exceptions due to
                        #interpreter shutdown, so blanket ignore those if
                        #the reporting fails
                        rospydebug(
                            "exception in receive loop for [%s], may be normal. Exception is %s",
                            self.name, traceback.format_exc())
                    except:
                        pass

            rospydebug("receive_loop[%s]: done condition met, exited loop" %
                       self.name)
        finally:
            if not self.done:
                self.close()
示例#3
0
 def write_data(self, data):
     """
     Write raw data to transport
     @raise TransportInitialiationError: could not be initialized
     @raise TransportTerminated: no longer open for publishing
     """
     if not self.socket:
         raise TransportInitError(
             "TCPROS transport was not successfully initialized")
     if self.done:
         raise TransportTerminated("connection closed")
     try:
         #TODO: get rid of sendalls and replace with async-style publishing
         self.socket.sendall(data.encode())
         self.stat_bytes += len(data)
         self.stat_num_msg += 1
     except IOError as xxx_todo_changeme:
         #for now, just document common errno's in code
         (errno, msg) = xxx_todo_changeme.args
         #for now, just document common errno's in code
         if errno == 32:  #broken pipe
             logdebug("ERROR: Broken Pipe")
             self.close()
             raise TransportTerminated(str(errno) + msg)
         raise  #re-raise
     except socket.error as xxx_todo_changeme1:
         #for now, just document common errno's in code
         (errno, msg) = xxx_todo_changeme1.args
         #for now, just document common errno's in code
         if errno == 32:  #broken pipe
             logdebug("[%s]: Closing connection [%s] due to broken pipe",
                      self.name, self.endpoint_id)
             self.close()
             raise TransportTerminated(msg)
         elif errno == 104:  #connection reset by peer
             logdebug("[%s]: Peer [%s] has closed connection", self.name,
                      self.endpoint_id)
             self.close()
             raise TransportTerminated(msg)
         else:
             rospydebug("unknown socket error writing data: %s",
                        traceback.format_exc())
             logdebug(
                 "[%s]: closing connection [%s] due to unknown socket error: %s",
                 self.name, self.endpoint_id, msg)
             self.close()
             raise TransportTerminated(str(errno) + ' ' + msg)
     #except:
     #TODO: try to figure out common errors here
     #raise
     return True
示例#4
0
 def write_data(self, data):
     """
     Write raw data to transport
     @raise TransportInitialiationError: could not be initialized
     @raise TransportTerminated: no longer open for publishing
     """
     if not self.socket:
         raise TransportInitError("TCPROS transport was not successfully initialized")
     if self.done:
         raise TransportTerminated("connection closed")
     try:
         #TODO: get rid of sendalls and replace with async-style publishing
         self.socket.sendall(data.encode())
         self.stat_bytes  += len(data)
         self.stat_num_msg += 1
     except IOError as xxx_todo_changeme:
         #for now, just document common errno's in code
         (errno, msg) = xxx_todo_changeme.args
         #for now, just document common errno's in code
         if errno == 32: #broken pipe
             logdebug("ERROR: Broken Pipe")
             self.close()
             raise TransportTerminated(str(errno)+msg)
         raise #re-raise
     except socket.error as xxx_todo_changeme1:
         #for now, just document common errno's in code
         (errno, msg) = xxx_todo_changeme1.args
         #for now, just document common errno's in code
         if errno == 32: #broken pipe
             logdebug("[%s]: Closing connection [%s] due to broken pipe", self.name, self.endpoint_id)
             self.close()
             raise TransportTerminated(msg)
         elif errno == 104: #connection reset by peer
             logdebug("[%s]: Peer [%s] has closed connection", self.name, self.endpoint_id) 
             self.close()
             raise TransportTerminated(msg)
         else:
             rospydebug("unknown socket error writing data: %s",traceback.format_exc())
             logdebug("[%s]: closing connection [%s] due to unknown socket error: %s", self.name, self.endpoint_id, msg) 
             self.close()
             raise TransportTerminated(str(errno)+' '+msg)                
     #except:
         #TODO: try to figure out common errors here
         #raise
     return True
示例#5
0
 def callback_loop(self, msgs_callback):
     while not self.done and not is_shutdown():
         try:
             with self.msg_queue_lock:
                 # Data that was leftover from reading header may have made
                 # messages immediately available (such as from a latched
                 # topic). Go ahead and process anything we already have before
                 # waiting.
                 while self.msg_queue:
                     msg = self.msg_queue.pop(0)
                     # Be sure to not hold the message queue lock while calling
                     # the callback, it may take a while.
                     self.msg_queue_lock.release()
                     msgs_callback([msg], self)
                     self.msg_queue_lock.acquire()
                 self.msg_queue_condition.wait()
         except:
             # in many cases this will be a normal hangup, but log internally
             try:
                 #1467 sometimes we get exceptions due to
                 #interpreter shutdown, so blanket ignore those if
                 #the reporting fails
                 rospydebug("exception in callback loop for [%s], may be normal. Exception is %s",self.name, traceback.format_exc())
             except: pass
示例#6
0
    def receive_loop(self, msgs_callback):
        """
        Receive messages until shutdown
        @param msgs_callback: callback to invoke for new messages received    
        @type  msgs_callback: fn([msg])
        """
        # - use assert here as this would be an internal error, aka bug
        logger.debug("receive_loop for [%s]", self.name)
        try:
            try:
                while not self.done and not is_shutdown():
                    msgs = self.receive_once()
                    if not self.done and not is_shutdown():
                        msgs_callback(msgs)

                rospydebug(
                    "receive_loop[%s]: done condition met, exited loop" %
                    self.name)
            except DeserializationError, e:
                logerr(
                    "[%s] error deserializing incoming request: %s" %
                    self.name, str(e))
                rospyerr(
                    "[%s] error deserializing incoming request: %s" %
                    self.name, traceback.format_exc())
            except:
                # in many cases this will be a normal hangup, but log internally
                try:
                    #1467 sometimes we get exceptions due to
                    #interpreter shutdown, so blanket ignore those if
                    #the reporting fails
                    rospydebug(
                        "exception in receive loop for [%s], may be normal. Exception is %s",
                        self.name, traceback.format_exc())
                except:
                    pass
示例#7
0
    def receive_loop(self, msgs_callback):
        """
        Receive messages until shutdown
        @param msgs_callback: callback to invoke for new messages received    
        @type  msgs_callback: fn([msg])
        """
        # - use assert here as this would be an internal error, aka bug
        logger.debug("receive_loop for [%s]", self.name)
        # Start a callback thread to process the callbacks. This way the
        # receive loop can continue calling recv() while a long-running
        # callback is running.
        try:
            self.msg_queue = []
            self.msg_queue_lock = threading.Lock()
            self.msg_queue_condition = threading.Condition(self.msg_queue_lock)
            callback_thread = threading.Thread(
                    target=self.callback_loop,
                    args=(msgs_callback,))
            callback_thread.start()
            while not self.done and not is_shutdown():
                try:
                    if self.socket is not None:
                        msgs = self.receive_once()
                        if not self.done and not is_shutdown():
                            with self.msg_queue_lock:
                                self.msg_queue += msgs
                                if self.protocol.queue_size is not None:
                                    self.msg_queue = self.msg_queue[-self.protocol.queue_size:]
                                self.msg_queue_condition.notify()
                    else:
                        self._reconnect()

                except TransportException as e:
                    # set socket to None so we reconnect
                    try:
                        if self.socket is not None:
                            try:
                                self.socket.shutdown()
                            except:
                                pass
                            finally:
                                self.socket.close()
                    except:
                        pass
                    self.socket = None

                except DeserializationError as e:
                    #TODO: how should we handle reconnect in this case?
                    
                    logerr("[%s] error deserializing incoming request: %s"%(self.name, str(e)))
                    rospyerr("[%s] error deserializing incoming request: %s"%(self.name, traceback.format_exc()))
                except:
                    # in many cases this will be a normal hangup, but log internally
                    try:
                        #1467 sometimes we get exceptions due to
                        #interpreter shutdown, so blanket ignore those if
                        #the reporting fails
                        rospydebug("exception in receive loop for [%s], may be normal. Exception is %s",self.name, traceback.format_exc())                    
                    except: pass
            with self.msg_queue_lock:
                self.msg_queue_condition.notify()
            callback_thread.join()
            rospydebug("receive_loop[%s]: done condition met, exited loop"%self.name)                    
        finally:
            if not self.done:
                self.close()
示例#8
0
                raise TransportTerminated(str(errno) + msg)
            raise  #re-raise
        except socket.error, (errno, msg):
            #for now, just document common errno's in code
            if errno == 32:  #broken pipe
                logdebug("[%s]: Closing connection [%s] due to broken pipe",
                         self.name, self.endpoint_id)
                self.close()
                raise TransportTerminated(msg)
            elif errno == 104:  #connection reset by peer
                logdebug("[%s]: Peer [%s] has closed connection", self.name,
                         self.endpoint_id)
                self.close()
                raise TransportTerminated(msg)
            else:
                rospydebug("unknown socket error writing data: %s",
                           traceback.format_exc())
                logdebug(
                    "[%s]: closing connection [%s] due to unknown socket error: %s",
                    self.name, self.endpoint_id, msg)
                self.close()
                raise TransportTerminated(str(errno) + ' ' + msg)
        except:
            #TODO: try to figure out common errors here
            raise
        return True

    def receive_once(self):
        """
        block until messages are read off of socket
        @return: list of newly received messages
        @rtype: [Msg]