Skip to content

Commit

Permalink
Use singleton approach to store and reuse the service clients (#1949)
Browse files Browse the repository at this point in the history
(cherry picked from commit b039baa)

# Conflicts:
#	controller_manager/controller_manager/controller_manager_services.py
  • Loading branch information
saikishor authored and mergify[bot] committed Dec 17, 2024
1 parent d7fcbca commit ce9d65f
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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 (node, fully_qualified_service_name) not in cls._clients:
cls._clients[(node, 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} with node : {node.get_name()}{bcolors.ENDC}"
)

node.get_logger().debug(
f"{bcolors.OKBLUE}Returning the existing service client : {fully_qualified_service_name} for node : {node.get_name()}{bcolors.ENDC}"
)
return cls._clients[(node, fully_qualified_service_name)]


def service_caller(
node,
service_name,
Expand Down Expand Up @@ -88,7 +117,15 @@ def service_caller(
@return The service response
"""
<<<<<<< HEAD
cli = node.create_client(service_type, service_name)
=======
namespace = "" if node.get_namespace() == "/" else node.get_namespace()
fully_qualified_service_name = (
f"{namespace}/{service_name}" if not service_name.startswith("/") else service_name
)
cli = SingletonServiceCaller(node, service_type, fully_qualified_service_name)
>>>>>>> b039baa (Use singleton approach to store and reuse the service clients (#1949))

while not cli.service_is_ready():
node.get_logger().info(f"waiting for service {service_name} to become available...")
Expand Down
1 change: 1 addition & 0 deletions controller_manager/controller_manager/spawner.py
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,7 @@ def main(args=None):
node.get_logger().fatal(str(err))
return 1
finally:
node.destroy_node()
rclpy.shutdown()


Expand Down

0 comments on commit ce9d65f

Please sign in to comment.