def send_message(self, msg, seq): """ Convenience routine for services to send a message across a particular connection. NOTE: write_data is much more efficient if same message is being sent to multiple connections. Not threadsafe. @param msg: message to send @type msg: Msg @param seq: sequence number for message @type seq: int @raise TransportException: if error occurred sending message """ # this will call write_data(), so no need to keep track of stats serialize_message(self.write_buff, seq, msg) self.write_data(self.write_buff.getvalue()) self.write_buff.truncate(0)
def publish(self, message, connection_override=None): """ Publish the data to the topic. If the topic has no subscribers, the method will return without any affect. Access to publish() should be locked using acquire() and release() in order to ensure proper message publish ordering. @param message: message data instance to publish @type message: L{Message} @param connection_override: publish to this connection instead of all @type connection_override: L{Transport} @return: True if the data was published, False otherwise. @rtype: bool @raise genpy.SerializationError: if L{Message} instance is unable to serialize itself @raise rospy.ROSException: if topic has been closed or was closed during publish() """ #TODO: should really just use IOError instead of rospy.ROSException if self.closed: # during shutdown, the topic can get closed, which creates # a race condition with user code testing is_shutdown if not is_shutdown(): raise ROSException("publish() to a closed topic") else: return if self.is_latch: self.latch = message if not self.has_connections(): #publish() falls through return False if connection_override is None: #copy connections so we can iterate safely conns = self.connections else: conns = [connection_override] # #2128 test our buffer. I don't now how this got closed in # that case, but we can at least diagnose the problem. b = self.buff try: b.tell() # serialize the message self.seq += 1 #count messages published to the topic serialize_message(b, self.seq, message) # send the buffer to all connections err_con = [] data = b.getvalue() for c in conns: try: if not is_shutdown(): c.write_data(data) except TransportTerminated as e: logdebug( "publisher connection to [%s] terminated, see errorlog for details:\n%s" % (c.endpoint_id, traceback.format_exc())) err_con.append(c) except Exception as e: # greater severity level logdebug( "publisher connection to [%s] terminated, see errorlog for details:\n%s" % (c.endpoint_id, traceback.format_exc())) err_con.append(c) # reset the buffer and update stats self.message_data_sent += b.tell() #STATS b.seek(0) b.truncate(0) except ValueError: # operations on self.buff can fail if topic is closed # during publish, which often happens during Ctrl-C. # diagnose the error and report accordingly. if self.closed: if is_shutdown(): # we offer no guarantees on publishes that occur # during shutdown, so this is not exceptional. return else: # this indicates that user-level code most likely # closed the topic, which is exceptional. raise ROSException("topic was closed during publish()") else: # unexpected, so re-raise original error raise # remove any bad connections for c in err_con: try: # connection will callback into remove_connection when # we close it c.close() except: pass
def publish(self, message, connection_override=None): """ Publish the data to the topic. If the topic has no subscribers, the method will return without any affect. Access to publish() should be locked using acquire() and release() in order to ensure proper message publish ordering. @param message: message data instance to publish @type message: L{Message} @param connection_override: publish to this connection instead of all @type connection_override: L{Transport} @return: True if the data was published, False otherwise. @rtype: bool @raise roslib.message.SerializationError: if L{Message} instance is unable to serialize itself @raise rospy.ROSException: if topic has been closed """ if self.closed: # during shutdown, the topic can get closed, which creates # a race condition with user code testing is_shutdown if not is_shutdown(): raise ROSException("publish() to a closed topic") else: return if self.is_latch: self.latch = message #print("Topic has connections: %s"%self.has_connections()) #print("(topics.py impl) --------------------> message is %s"%message) if not self.has_connections(): #publish() falls through return False if connection_override is None: #copy connections so we can iterate safely conns = self.connections else: conns = [connection_override] # #2128 test our buffer. I don't now how this got closed in # that case, but we can at least diagnose the problem. b = self.buff try: b.tell() except ValueError: raise ROSException("topic's internal buffer is no longer valid") # serialize the message self.seq += 1 #count messages published to the topic serialize_message(b, self.seq, message) # send the buffer to all connections err_con = [] data = b.getvalue() for c in conns: try: c.write_data(data) except TransportTerminated as e: logdebug( "publisher connection to [%s] terminated, see errorlog for details:\n%s" % (c.endpoint_id, traceback.format_exc())) err_con.append(c) except Exception as e: # greater severity level logdebug( "publisher connection to [%s] terminated, see errorlog for details:\n%s" % (c.endpoint_id, traceback.format_exc())) err_con.append(c) # reset the buffer and update stats self.message_data_sent += b.tell() #STATS b.seek(0) b.truncate(0) # remove any bad connections for c in err_con: try: # connection will callback into remove_connection when # we close it c.close() except: pass
def publish(self, message, connection_override=None): """ Publish the data to the topic. If the topic has no subscribers, the method will return without any affect. Access to publish() should be locked using acquire() and release() in order to ensure proper message publish ordering. @param message: message data instance to publish @type message: L{Message} @param connection_override: publish to this connection instead of all @type connection_override: L{Transport} @return: True if the data was published, False otherwise. @rtype: bool @raise genpy.SerializationError: if L{Message} instance is unable to serialize itself @raise rospy.ROSException: if topic has been closed or was closed during publish() """ # TODO: should really just use IOError instead of rospy.ROSException if self.closed: # during shutdown, the topic can get closed, which creates # a race condition with user code testing is_shutdown if not is_shutdown(): raise ROSException("publish() to a closed topic") else: return if self.is_latch: self.latch = message if not self.has_connections(): # publish() falls through return False if connection_override is None: # copy connections so we can iterate safely conns = self.connections else: conns = [connection_override] # #2128 test our buffer. I don't now how this got closed in # that case, but we can at least diagnose the problem. b = self.buff try: b.tell() # serialize the message self.seq += 1 # count messages published to the topic serialize_message(b, self.seq, message) # send the buffer to all connections err_con = [] data = b.getvalue() for c in conns: try: if not is_shutdown(): c.write_data(data) except TransportTerminated as e: logdebug( "publisher connection to [%s] terminated, see errorlog for details:\n%s" % (c.endpoint_id, traceback.format_exc()) ) err_con.append(c) except Exception as e: # greater severity level logdebug( "publisher connection to [%s] terminated, see errorlog for details:\n%s" % (c.endpoint_id, traceback.format_exc()) ) err_con.append(c) # reset the buffer and update stats self.message_data_sent += b.tell() # STATS b.seek(0) b.truncate(0) except ValueError: # operations on self.buff can fail if topic is closed # during publish, which often happens during Ctrl-C. # diagnose the error and report accordingly. if self.closed: if is_shutdown(): # we offer no guarantees on publishes that occur # during shutdown, so this is not exceptional. return else: # this indicates that user-level code most likely # closed the topic, which is exceptional. raise ROSException("topic was closed during publish()") else: # unexpected, so re-raise original error raise # remove any bad connections for c in err_con: try: # connection will callback into remove_connection when # we close it c.close() except: pass
def publish(self, message, connection_override=None): """ Publish the data to the topic. If the topic has no subscribers, the method will return without any affect. Access to publish() should be locked using acquire() and release() in order to ensure proper message publish ordering. @param message: message data instance to publish @type message: L{Message} @param connection_override: publish to this connection instead of all @type connection_override: L{Transport} @return: True if the data was published, False otherwise. @rtype: bool @raise roslib.message.SerializationError: if L{Message} instance is unable to serialize itself @raise rospy.ROSException: if topic has been closed """ if self.closed: # during shutdown, the topic can get closed, which creates # a race condition with user code testing is_shutdown if not is_shutdown(): raise ROSException("publish() to a closed topic") else: return if self.is_latch: self.latch = message #print("Topic has connections: %s"%self.has_connections()) #print("(topics.py impl) --------------------> message is %s"%message) if not self.has_connections(): #publish() falls through return False if connection_override is None: #copy connections so we can iterate safely conns = self.connections else: conns = [connection_override] # #2128 test our buffer. I don't now how this got closed in # that case, but we can at least diagnose the problem. b = self.buff try: b.tell() except ValueError: raise ROSException("topic's internal buffer is no longer valid") # serialize the message self.seq += 1 #count messages published to the topic serialize_message(b, self.seq, message) # send the buffer to all connections err_con = [] data = b.getvalue() for c in conns: try: c.write_data(data) except TransportTerminated as e: logdebug("publisher connection to [%s] terminated, see errorlog for details:\n%s"%(c.endpoint_id, traceback.format_exc())) err_con.append(c) except Exception as e: # greater severity level logdebug("publisher connection to [%s] terminated, see errorlog for details:\n%s"%(c.endpoint_id, traceback.format_exc())) err_con.append(c) # reset the buffer and update stats self.message_data_sent += b.tell() #STATS b.seek(0) b.truncate(0) # remove any bad connections for c in err_con: try: # connection will callback into remove_connection when # we close it c.close() except: pass