Exemplo n.º 1
0
    def reg_added(self, resolved_name, data_type_or_uri, reg_type):
        """
        RegistrationListener callback
        @param resolved_name: resolved name of topic or service
        @type  resolved_name: str
        @param data_type_or_uri: either the data type (for topic regs) or the service URI (for service regs).
        @type  data_type_or_uri: str
        @param reg_type: Valid values are L{Registration.PUB}, L{Registration.SUB}, L{Registration.SRV}
        @type  reg_type: str
        """
        #TODO: this needs to be made robust to master outages
        master_uri = self.master_uri
        if not master_uri:
            self.logger.error(
                "Registrar: master_uri is not set yet, cannot inform master of registration"
            )
        else:
            master = xmlrpcapi(master_uri)
            args = (get_caller_id(), resolved_name, data_type_or_uri, self.uri)
            registered = False
            first = True
            while not registered and not is_shutdown():
                try:
                    if reg_type == Registration.PUB:
                        self.logger.debug(
                            "master.registerPublisher(%s, %s, %s, %s)" % args)
                        code, msg, val = master.registerPublisher(*args)
                        if code != 1:
                            logfatal(
                                "unable to register publication [%s] with master: %s"
                                % (resolved_name, msg))
                    elif reg_type == Registration.SUB:
                        self.logger.debug(
                            "master.registerSubscriber(%s, %s, %s, %s)" % args)
                        code, msg, val = master.registerSubscriber(*args)
                        if code == 1:
                            self.publisher_update(resolved_name, val)
                        else:
                            # this is potentially worth exiting over. in the future may want to add a retry
                            # timer
                            logfatal(
                                "unable to register subscription [%s] with master: %s"
                                % (resolved_name, msg))
                    elif reg_type == Registration.SRV:
                        self.logger.debug(
                            "master.registerService(%s, %s, %s, %s)" % args)
                        code, msg, val = master.registerService(*args)
                        if code != 1:
                            logfatal(
                                "unable to register service [%s] with master: %s"
                                % (resolved_name, msg))

                    registered = True
                except Exception as e:
                    if first:
                        msg = "Unable to register with master node [%s]: master may not be running yet. Will keep trying." % master_uri
                        self.logger.error(str(e) + "\n" + msg)
                        print(msg)
                        first = False
                    time.sleep(0.2)
 def reg_removed(self, resolved_name, data_type_or_uri, reg_type):
     """
     RegistrationListener callback
     @param resolved_name: resolved name of topic or service
     @type  resolved_name: str
     @param data_type_or_uri: either the data type (for topic regs) or the service URI (for service regs).
     @type  data_type_or_uri: str
     @param reg_type: Valid values are L{Registration.PUB}, L{Registration.SUB}, L{Registration.SRV}
     @type  reg_type: str
     """
     master_uri = self.master_uri
     if not master_uri:
         self.logger.error("Registrar: master_uri is not set yet, cannot inform master of deregistration")
     else:
         try:
             master = xmlrpcapi(master_uri)
             if reg_type == Registration.PUB:
                 self.logger.debug("unregisterPublisher(%s, %s)", resolved_name, self.uri)
                 master.unregisterPublisher(get_caller_id(), resolved_name, self.uri)
             elif reg_type == Registration.SUB:            
                 self.logger.debug("unregisterSubscriber(%s, %s)", resolved_name, data_type_or_uri)
                 master.unregisterSubscriber(get_caller_id(), resolved_name, self.uri)
             elif reg_type == Registration.SRV:
                 self.logger.debug("unregisterService(%s, %s)", resolved_name, data_type_or_uri)
                 master.unregisterService(get_caller_id(), resolved_name, data_type_or_uri)
         except:
             logwarn("unable to communicate with ROS Master, registrations are now out of sync")
             self.logger.error(traceback.format_exc())
Exemplo n.º 3
0
    def reg_added(self, resolved_name, data_type_or_uri, reg_type):
        """
        RegistrationListener callback
        @param resolved_name: resolved name of topic or service
        @type  resolved_name: str
        @param data_type_or_uri: either the data type (for topic regs) or the service URI (for service regs).
        @type  data_type_or_uri: str
        @param reg_type: Valid values are L{Registration.PUB}, L{Registration.SUB}, L{Registration.SRV}
        @type  reg_type: str
        """
        # TODO: this needs to be made robust to master outages
        master_uri = self.master_uri
        if not master_uri:
            self.logger.error("Registrar: master_uri is not set yet, cannot inform master of registration")
        else:
            master = xmlrpcapi(master_uri)
            args = (get_caller_id(), resolved_name, data_type_or_uri, self.uri)
            registered = False
            first = True
            while not registered and not is_shutdown():
                try:
                    if reg_type == Registration.PUB:
                        self.logger.debug("master.registerPublisher(%s, %s, %s, %s)" % args)
                        code, msg, val = master.registerPublisher(*args)
                        if code != 1:
                            logfatal("unable to register publication [%s] with master: %s" % (resolved_name, msg))
                    elif reg_type == Registration.SUB:
                        self.logger.debug("master.registerSubscriber(%s, %s, %s, %s)" % args)
                        code, msg, val = master.registerSubscriber(*args)
                        if code == 1:
                            self.publisher_update(resolved_name, val)
                        else:
                            # this is potentially worth exiting over. in the future may want to add a retry
                            # timer
                            logfatal("unable to register subscription [%s] with master: %s" % (resolved_name, msg))
                    elif reg_type == Registration.SRV:
                        self.logger.debug("master.registerService(%s, %s, %s, %s)" % args)
                        code, msg, val = master.registerService(*args)
                        if code != 1:
                            logfatal("unable to register service [%s] with master: %s" % (resolved_name, msg))

                    registered = True
                except Exception as e:
                    if first:
                        msg = (
                            "Unable to register with master node [%s]: master may not be running yet. Will keep trying."
                            % master_uri
                        )
                        self.logger.error(str(e) + "\n" + msg)
                        print(msg)
                        first = False
                    time.sleep(0.2)
Exemplo n.º 4
0
    def cleanup(self, reason):
        """
        Cleans up registrations with master and releases topic and service resources
        @param reason: human-reasonable debug string
        @type  reason: str
        """
        self.logger.debug("registration cleanup starting")
        try:
            self.cond.acquire()
            self.cond.notifyAll()
        finally:
            self.cond.release()

        # we never successfully initialized master_uri
        if not self.master_uri:
            return

        master = xmlrpcapi(self.master_uri)
        # we never successfully initialized master
        if master is None:
            return

        caller_id = get_caller_id()

        tm = get_topic_manager()
        sm = get_service_manager()
        try:
            if tm is not None:
                for resolved_name, _ in tm.get_subscriptions():
                    self.logger.debug("unregisterSubscriber [%s]" %
                                      resolved_name)
                    master.unregisterSubscriber(caller_id, resolved_name,
                                                self.uri)
                for resolved_name, _ in tm.get_publications():
                    self.logger.debug("unregisterPublisher [%s]" %
                                      resolved_name)
                    master.unregisterPublisher(caller_id, resolved_name,
                                               self.uri)

            if sm is not None:
                for resolved_name, service_uri in sm.get_services():
                    self.logger.debug("unregisterService [%s]" % resolved_name)
                    master.unregisterService(caller_id, resolved_name,
                                             service_uri)
        except socket.error, (errno, msg):
            if errno == 111 or errno == 61:  #can't talk to master, nothing we can do about it
                self.logger.warn(
                    "cannot unregister with master due to network issues")
            else:
                self.logger.warn("unclean shutdown\n%s" %
                                 traceback.format_exc())
    def cleanup(self, reason):
        """
        Cleans up registrations with master and releases topic and service resources
        @param reason: human-reasonable debug string
        @type  reason: str
        """
        self.logger.debug("registration cleanup starting")
        try:
            self.cond.acquire()
            self.cond.notifyAll()
        finally:
            self.cond.release()        

        # we never successfully initialized master_uri
        if not self.master_uri:
            return
        
        master = xmlrpcapi(self.master_uri)
        # we never successfully initialized master
        if master is None:
            return
        
        caller_id = get_caller_id()

        # clear the registration listeners as we are going to do a quick unregister here
        rl = get_registration_listeners()
        if rl is not None:
            rl.clear()
            
        tm = get_topic_manager()
        sm = get_service_manager()
        try:
            multi = xmlrpcclient.MultiCall(master)
            if tm is not None:
                for resolved_name, _ in tm.get_subscriptions():
                    self.logger.debug("unregisterSubscriber [%s]"%resolved_name)
                    multi.unregisterSubscriber(caller_id, resolved_name, self.uri)
                for resolved_name, _ in tm.get_publications():
                    self.logger.debug("unregisterPublisher [%s]"%resolved_name)                    
                    multi.unregisterPublisher(caller_id, resolved_name, self.uri)

            if sm is not None:
                for resolved_name, service_uri in sm.get_services():
                    self.logger.debug("unregisterService [%s]"%resolved_name) 
                    multi.unregisterService(caller_id, resolved_name, service_uri)
            multi()
        except socket.error as se:
            (errno, msg) = se.args
            if errno == 111 or errno == 61: #can't talk to master, nothing we can do about it
                self.logger.warn("cannot unregister with master due to network issues")
            else:
                self.logger.warn("unclean shutdown\n%s"%traceback.format_exc())
        except:
            self.logger.warn("unclean shutdown\n%s"%traceback.format_exc())

        self.logger.debug("registration cleanup: master calls complete")            

        #TODO: cleanup() should actually be orchestrated by a separate
        #cleanup routine that calls the reg manager/sm/tm
        if tm is not None:
            tm.close_all()
        if sm is not None:
            sm.unregister_all()
    def start(self, uri, master_uri):
        """
        Start the RegManager. This should be passed in as an argument to a thread
        starter as the RegManager is designed to spin in its own thread
        @param uri: URI of local node
        @type  uri: str
        @param master_uri: Master URI
        @type  master_uri: str
        """
        self.registered = False 
        self.master_uri = master_uri
        self.uri = uri
        first = True
        tm = get_topic_manager()
        sm = get_service_manager()
        ns = get_namespace()
        caller_id = get_caller_id()
        if not master_uri or master_uri == uri:
            registered = True
            master = None
        else:
            registered = False
            master = xmlrpcapi(master_uri)
            self.logger.info("Registering with master node %s", master_uri)

        while not registered and not is_shutdown():
            try:
                try:
                    # prevent TopicManager and ServiceManager from accepting registrations until we are done
                    tm.lock.acquire()
                    sm.lock.acquire()                    

                    pub, sub, srv = tm.get_publications(), tm.get_subscriptions(), sm.get_services()
                    for resolved_name, data_type in pub:
                        self.logger.info("Registering publisher topic [%s] type [%s] with master", resolved_name, data_type)
                        code, msg, val = master.registerPublisher(caller_id, resolved_name, data_type, uri)
                        if code != 1:
                            logfatal("cannot register publication topic [%s] with master: %s"%(resolved_name, msg))
                            signal_shutdown("master/node incompatibility with register publisher")
                    for resolved_name, data_type in sub:
                        self.logger.info("registering subscriber topic [%s] type [%s] with master", resolved_name, data_type)
                        code, msg, val = master.registerSubscriber(caller_id, resolved_name, data_type, uri)
                        if code != 1:
                            logfatal("cannot register subscription topic [%s] with master: %s"%(resolved_name, msg))
                            signal_shutdown("master/node incompatibility with register subscriber")                        
                        else:
                            self.publisher_update(resolved_name, val)
                    for resolved_name, service_uri in srv:
                        self.logger.info("registering service [%s] uri [%s] with master", resolved_name, service_uri)
                        code, msg, val = master.registerService(caller_id, resolved_name, service_uri, uri)
                        if code != 1:
                            logfatal("cannot register service [%s] with master: %s"%(resolved_name, msg))
                            signal_shutdown("master/node incompatibility with register service")                        
 
                    registered = True
                    
                    # Subscribe to updates to our state
                    get_registration_listeners().add_listener(self)
                finally:
                    sm.lock.release()                    
                    tm.lock.release()
                
                if pub or sub:
                    logdebug("Registered [%s] with master node %s", caller_id, master_uri)
                else:
                    logdebug("No topics to register with master node %s", master_uri)
                    
            except Exception as e:
                if first:
                    # this use to print to console always, arguable whether or not this should be subjected to same configuration options as logging
                    logerr("Unable to immediately register with master node [%s]: master may not be running yet. Will keep trying."%master_uri)
                    first = False
                time.sleep(0.2)
        self.registered = True
        self.run()
Exemplo n.º 7
0
def get_master_xmlrpcapi(uri):
    return xmlrpcapi(uri)