# Use callback groups to allow an Action to trigger a service of the same Node

I have a Node that hosts an Action and a Service Client:

    callback_group=ReentrantCallbackGroup()
self.__driver = GrappleCraneDriverClient(self, callback_group)

self.move_joint_absolute_action_server = ActionServer(self,
action_type=MoveJointAbsolute,
action_name='move_joint_absolute',
execute_callback=move_joint_absolute_execute_callback,
goal_callback=move_joint_absolute_goal_callback,
cancel_callback=move_joint_absolute_cancel_callback,
callback_group=callback_group
)


The service client adds clients to the Node:

class GrappleCraneDriverClient:

def __init__(self, node: Node, callback_group=None):

self.__node = node

# Service clients

self.__move_x_abs=node.create_client(
srv_type=MoveOneAxis,
srv_name='accs/grapple_crane/service/move_x_abs',
callback_group=callback_group
)

def move_x_abs(self, target_position: float) -> MoveOneAxis_Response:
self.__node.get_logger().info(
f'[GrappleCraneDriverClient]: calling service {self.__move_x_abs.srv_name}')

future_trigger_result = self.__move_x_abs.call_async(
MoveOneAxis_Request(target_position=target_position))
try:
return asyncio.run(asyncio.wait_for(future_trigger_result, timeout=5))
except asyncio.TimeoutError as e:
self.__node.get_logger().error(f'TimeoutError: {e}')
return MoveOneAxis_Response(success=False, message=f'TimeoutError: {e}')


The Node hosting the services is running in a different process.

If I test the GrappleCraneDriverClient by constructing it with a new Node, and then launching it in the same process as the Node that hosts the services, then it works fine.

However when I use the GrappleCraneDriverClient to compose part of my Node that hosts the actions, then I get a timeout error because the service never gets called.

Why would this be?

A key difference between the test code (which works), and the action server code is that in the action server a callback is already running (the move_joint_absolute_execute_callback) when the service is called. However, I am using a ReentrantCallbackGroup(), so this should allow the callbacks to run at the same time, should it not?

I am also using a MultiThreadedExecutor.

If I give the GrappleCraneDriverClient a new Node and run that Node alongside the Node hosting the action (but still in the same process), it also works.

How do I correctly get the service to be called while the action is running, and have the client and action server elonging to the same Node?

Thanks.

edit retag close merge delete