diff --git a/controller_manager/controller_manager/controller_manager_services.py b/controller_manager/controller_manager/controller_manager_services.py index bfe36fe3b7..d41ed93a6f 100644 --- a/controller_manager/controller_manager/controller_manager_services.py +++ b/controller_manager/controller_manager/controller_manager_services.py @@ -55,6 +55,35 @@ class ServiceNotFoundError(Exception): pass +class SingletonServiceCaller: + """ + Singleton class to call services of controller manager. + + This class is used to create a service client for a given service name. + If the service client already exists, it returns the existing client. + It is used to avoid creating multiple service clients for the same service name. + + It needs Node object, service type and fully qualified service name to create a service client. + + """ + + _clients = {} + + def __new__(cls, node, service_type, fully_qualified_service_name): + if fully_qualified_service_name not in cls._clients: + cls._clients[fully_qualified_service_name] = node.create_client( + service_type, fully_qualified_service_name + ) + node.get_logger().debug( + f"{bcolors.MAGENTA}Creating a new service client : {fully_qualified_service_name}{bcolors.ENDC}" + ) + + node.get_logger().debug( + f"{bcolors.OKBLUE}Returning the existing service client : {fully_qualified_service_name}{bcolors.ENDC}" + ) + return cls._clients[fully_qualified_service_name] + + def service_caller( node, service_name, @@ -92,7 +121,7 @@ def service_caller( fully_qualified_service_name = ( f"{namespace}/{service_name}" if not service_name.startswith("/") else service_name ) - cli = node.create_client(service_type, fully_qualified_service_name) + cli = SingletonServiceCaller(node, service_type, fully_qualified_service_name) while not cli.service_is_ready(): node.get_logger().info( diff --git a/controller_manager/controller_manager/spawner.py b/controller_manager/controller_manager/spawner.py index c5a23defe4..b8abe8469f 100644 --- a/controller_manager/controller_manager/spawner.py +++ b/controller_manager/controller_manager/spawner.py @@ -342,6 +342,7 @@ def main(args=None): node.get_logger().fatal(str(err)) return 1 finally: + node.destroy_node() rclpy.shutdown()