def start(self): """ Startup roslaunch server XML-RPC services @raise RLException: if server fails to start """ logger = logging.getLogger('roslaunch.server') logger.info("starting roslaunch XML-RPC server") super(ROSLaunchNode, self).start() # wait for node thread to initialize timeout_t = time.time() + _STARTUP_TIMEOUT logger.info("waiting for roslaunch XML-RPC server to initialize") while not self.uri and time.time() < timeout_t: time.sleep(0.01) if not self.uri: raise RLException("XML-RPC initialization failed") # Make sure our xmlrpc server is actually up. We've seen very # odd cases where remote nodes are unable to contact the # server but have been unable to prove this is the cause. server_up = False while not server_up and time.time() < timeout_t: try: code, msg, val = ServerProxy(self.uri).get_pid() if val != os.getpid(): raise RLException( "Server at [%s] did not respond with correct PID. There appears to be something wrong with the networking configuration" % self.uri) server_up = True except IOError: # presumably this can occur if we call in a small time # interval between the server socket port being # assigned and the XMLRPC server initializing, but it # is highly unlikely and unconfirmed time.sleep(0.1) except socket.error as e: if e.errno == 113: p = urlparse(self.uri) raise RLException( "Unable to contact the address [%s], which should be local.\nThis is generally caused by:\n * bad local network configuration\n * bad ROS_IP environment variable\n * bad ROS_HOSTNAME environment variable\nCan you ping %s?" % (self.uri, p.hostname)) else: time.sleep(0.1) if not server_up: p = urlparse(self.uri) raise RLException("""Unable to contact my own server at [%s]. This usually means that the network is not configured properly. A common cause is that the machine cannot connect to itself. Please check for errors by running: \tping %s For more tips, please see \thttp://www.ros.org/wiki/ROS/NetworkSetup """ % (self.uri, p.hostname)) printlog_bold("started roslaunch server %s" % (self.uri))
def start(self): """ Startup roslaunch server XML-RPC services @raise RLException: if server fails to start """ logger = logging.getLogger('roslaunch.server') logger.info("starting roslaunch XML-RPC server") super(ROSLaunchNode, self).start() # wait for node thread to initialize timeout_t = time.time() + _STARTUP_TIMEOUT logger.info("waiting for roslaunch XML-RPC server to initialize") while not self.uri and time.time() < timeout_t: time.sleep(0.01) if not self.uri: raise RLException("XML-RPC initialization failed") # Make sure our xmlrpc server is actually up. We've seen very # odd cases where remote nodes are unable to contact the # server but have been unable to prove this is the cause. server_up = False while not server_up and time.time() < timeout_t: try: code, msg, val = ServerProxy(self.uri).get_pid() if val != os.getpid(): raise RLException("Server at [%s] did not respond with correct PID. There appears to be something wrong with the networking configuration"%self.uri) server_up = True except IOError: # presumably this can occur if we call in a small time # interval between the server socket port being # assigned and the XMLRPC server initializing, but it # is highly unlikely and unconfirmed time.sleep(0.1) except socket.error as e: if e.errno == 113: p = urlparse(self.uri) raise RLException("Unable to contact the address [%s], which should be local.\nThis is generally caused by:\n * bad local network configuration\n * bad ROS_IP environment variable\n * bad ROS_HOSTNAME environment variable\nCan you ping %s?"%(self.uri, p.hostname)) else: time.sleep(0.1) if not server_up: p = urlparse(self.uri) raise RLException("""Unable to contact my own server at [%s]. This usually means that the network is not configured properly. A common cause is that the machine cannot ping itself. Please check for errors by running: \tping %s For more tips, please see \thttp://www.ros.org/wiki/ROS/NetworkSetup """%(self.uri, p.hostname)) printlog_bold("started roslaunch server %s"%(self.uri))
def test_printlog(self): from roslaunch.core import add_printlog_handler, add_printerrlog_handler, printlog, printlog_bold, printerrlog add_printlog_handler(printlog_cb) add_printlog_handler(printlog_cb_exception) add_printerrlog_handler(printlog_cb) add_printerrlog_handler(printlog_cb_exception) #can't really test functionality, just make sure it doesn't crash global _lastmsg _lastmsg = None printlog('foo') self.assertEquals('foo', _lastmsg) printlog_bold('bar') self.assertEquals('bar', _lastmsg) printerrlog('baz') self.assertEquals('baz', _lastmsg)
class ROSLaunchNode(xmlrpc.XmlRpcNode): """ Base XML-RPC server for roslaunch parent/child processes """ def __init__(self, handler): """ @param handler: xmlrpc api handler @type handler: L{ROSLaunchBaseHandler} """ super(ROSLaunchNode, self).__init__(0, handler) def start(self): """ Startup roslaunch server XML-RPC services @raise RLException: if server fails to start """ logger = logging.getLogger('roslaunch.server') logger.info("starting roslaunch XML-RPC server") super(ROSLaunchNode, self).start() # wait for node thread to initialize timeout_t = time.time() + _STARTUP_TIMEOUT logger.info("waiting for roslaunch XML-RPC server to initialize") while not self.uri and time.time() < timeout_t: time.sleep(0.01) if not self.uri: raise RLException("XML-RPC initialization failed") # Make sure our xmlrpc server is actually up. We've seen very # odd cases where remote nodes are unable to contact the # server but have been unable to prove this is the cause. server_up = False while not server_up and time.time() < timeout_t: try: code, msg, val = xmlrpclib.ServerProxy(self.uri).get_pid() if val != os.getpid(): raise RLException( "Server at [%s] did not respond with correct PID. There appears to be something wrong with the networking configuration" % self.uri) server_up = True except IOError: # presumably this can occur if we call in a small time # interval between the server socket port being # assigned and the XMLRPC server initializing, but it # is highly unlikely and unconfirmed time.sleep(0.1) except socket.error, (errno, msg): if errno == 113: p = urlparse.urlparse(self.uri) raise RLException( "Unable to contact the address [%s], which should be local.\nThis is generally caused by:\n * bad local network configuration\n * bad ROS_IP environment variable\n * bad ROS_HOSTNAME environment variable\nCan you ping %s?" % (self.uri, p.hostname)) else: time.sleep(0.1) if not server_up: raise RLException( "Unable to contact my own XML-RPC server, this is a highly unusual error and should be reported immediately.\nMy URI is [%s]" % self.uri) printlog_bold("started roslaunch server %s" % self.uri)
def _init_remote(self): """ Initialize the remote process runner, if required. Subroutine of _start_remote, separated out for easier testing """ if self.config is None: raise RLException("config is not initialized") if self.pm is None: raise RLException("pm is not initialized") if self.server is None: raise RLException("server is not initialized") if not self.local_only and self.config.has_remote_nodes(): # keep the remote package lazy-imported import roslaunch.remote self.remote_runner = roslaunch.remote.ROSRemoteRunner(self.run_id, self.config, self.pm, self.server) elif self.local_only: printlog_bold("LOCAL\nlocal only launch specified, will not launch remote nodes\nLOCAL\n")
def log(self, client, level, message): """ Report a log message to the server @param client: name of client @type client: str @param level: log level (uses rosgraph_msgs.msg.Log levels) @type level: int @param message: message to log @type message: str """ try: if level >= Log.ERROR: printerrlog("[%s]: %s" % (client, message)) else: #hack due to the fact that we only have one INFO level if 'started with pid' in message: printlog_bold("[%s]: %s" % (client, message)) else: printlog("[%s]: %s" % (client, message)) except: # can't trust the logging system at this point, so just dump to screen traceback.print_exc() return 1, '', 1
def log(self, client, level, message): """ Report a log message to the server @param client: name of client @type client: str @param level: log level (uses roslib.msg.Log levels) @type level: int @param message: message to log @type message: str """ try: if level >= Log.ERROR: printerrlog("[%s]: %s"%(client, message)) else: #hack due to the fact that we only have one INFO level if 'started with pid' in message: printlog_bold("[%s]: %s"%(client, message)) else: printlog("[%s]: %s"%(client, message)) except: # can't trust the logging system at this point, so just dump to screen traceback.print_exc() return 1, '', 1
def _run(self): """ Internal run loop of ProcessMonitor """ plock = self.plock dead = [] respawn = [] while not self._registrations_complete: logger.info("mirko hack") time.sleep(0.1) #yield thread while not self.is_shutdown: with plock: #copy self.procs procs = self.procs[:] if self.is_shutdown: break # check current signal handlers to see if children have stolen them away # TODO: this code may not be necessary anymore (have to test) for s in _signal_list: if signal.getsignal(s) != rl_signal: self.reacquire_signals.add(s) for p in procs: try: if not p.is_alive(): logger.debug( "Process[%s] has died, respawn=%s, required=%s, exit_code=%s", p.name, "True(%f)" % p.respawn_delay if p.respawn else p.respawn, p.required, p.exit_code) exit_code_str = p.get_exit_description() if p.required: printerrlog( '=' * 80 + "REQUIRED process [%s] has died!\n%s\nInitiating shutdown!\n" % (p.name, exit_code_str) + '=' * 80) self.is_shutdown = True elif not p in respawn: if p.exit_code: printerrlog("[%s] %s" % (p.name, exit_code_str)) else: printlog_bold("[%s] %s" % (p.name, exit_code_str)) dead.append(p) ## no need for lock as we require listeners be ## added before process monitor is launched for l in self.listeners: l.process_died(p.name, p.exit_code) except Exception as e: traceback.print_exc() #don't respawn as this is an internal error dead.append(p) if self.is_shutdown: break #stop polling for d in dead: try: # when should_respawn() returns 0.0, bool(0.0) evaluates to False # work around this by checking if the return value is False if d.should_respawn() is not False: respawn.append(d) else: self.unregister(d) # stop process, don't accumulate errors d.stop([]) # save process data to dead list with plock: self.dead_list.append(DeadProcess(d)) except: logger.error(traceback.format_exc()) # dead check is to make sure that ProcessMonitor at least # waits until its had at least one process before exiting if self._registrations_complete and dead and not self.procs and not respawn: printlog( "all processes on machine have died, roslaunch will exit") self.is_shutdown = True del dead[:] _respawn = [] for r in respawn: try: if self.is_shutdown: break if r.should_respawn() <= 0.0: printlog("[%s] restarting process" % r.name) # stop process, don't accumulate errors r.stop([]) r.start() else: # not ready yet, keep it around _respawn.append(r) except: traceback.print_exc() logger.error("Restart failed %s", traceback.format_exc()) respawn = _respawn time.sleep(0.1) #yield thread
def _run(self): """ Internal run loop of ProcessMonitor """ plock = self.plock dead = [] respawn = [] while not self.is_shutdown: with plock: # copy self.procs procs = self.procs[:] if self.is_shutdown: break # check current signal handlers to see if children have stolen them away # TODO: this code may not be necessary anymore (have to test) for s in _signal_list: if signal.getsignal(s) != rl_signal: self.reacquire_signals.add(s) for p in procs: try: if not p.is_alive(): logger.debug( "Process[%s] has died, respawn=%s, required=%s, exit_code=%s", p.name, "True(%f)" % p.respawn_delay if p.respawn else p.respawn, p.required, p.exit_code, ) exit_code_str = p.get_exit_description() if p.required: printerrlog( "=" * 80 + "REQUIRED process [%s] has died!\n%s\nInitiating shutdown!\n" % (p.name, exit_code_str) + "=" * 80 ) self.is_shutdown = True elif not p in respawn: if p.exit_code: printerrlog("[%s] %s" % (p.name, exit_code_str)) else: printlog_bold("[%s] %s" % (p.name, exit_code_str)) dead.append(p) ## no need for lock as we require listeners be ## added before process monitor is launched for l in self.listeners: l.process_died(p.name, p.exit_code) except Exception as e: traceback.print_exc() # don't respawn as this is an internal error dead.append(p) if self.is_shutdown: break # stop polling for d in dead: try: if d.should_respawn(): respawn.append(d) else: self.unregister(d) # stop process, don't accumulate errors d.stop([]) # save process data to dead list with plock: self.dead_list.append(DeadProcess(d)) except: logger.error(traceback.format_exc()) # dead check is to make sure that ProcessMonitor at least # waits until its had at least one process before exiting if self._registrations_complete and dead and not self.procs and not respawn: printlog("all processes on machine have died, roslaunch will exit") self.is_shutdown = True del dead[:] _respawn = [] for r in respawn: try: if self.is_shutdown: break if r.should_respawn() <= 0.0: printlog("[%s] restarting process" % r.name) # stop process, don't accumulate errors r.stop([]) r.start() else: # not ready yet, keep it around _respawn.append(r) except: traceback.print_exc() logger.error("Restart failed %s", traceback.format_exc()) respawn = _respawn time.sleep(0.1) # yield thread