Skip to content

Commit c37340d

Browse files
authored
check for shutdown while waiting for a service response to avoid hang during shutdown (#104)
* check for shutdown while waiting for a service response to avoid hang during shutdown Signed-off-by: William Woodall <[email protected]> * fix typo in logger call Signed-off-by: William Woodall <[email protected]>
1 parent 35c84cb commit c37340d

File tree

1 file changed

+26
-2
lines changed

1 file changed

+26
-2
lines changed

launch_ros/launch_ros/actions/lifecycle_node.py

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
"""Module for the LifecycleNode action."""
1616

1717
import functools
18+
import threading
1819
from typing import cast
1920
from typing import List
2021
from typing import Optional
@@ -77,12 +78,35 @@ def _on_transition_event(self, context, msg):
7778
def _call_change_state(self, request, context: launch.LaunchContext):
7879
while not self.__rclpy_change_state_client.wait_for_service(timeout_sec=1.0):
7980
if context.is_shutdown:
80-
self.___logger.warning(
81+
self.__logger.warning(
8182
"Abandoning wait for the '{}' service, due to shutdown.".format(
8283
self.__rclpy_change_state_client.srv_name),
8384
)
8485
return
85-
response = self.__rclpy_change_state_client.call(request)
86+
87+
# Asynchronously wait so that we can periodically check for shutdown.
88+
event = threading.Event()
89+
90+
def unblock(future):
91+
nonlocal event
92+
event.set()
93+
94+
response_future = self.__rclpy_change_state_client.call_async(request)
95+
response_future.add_done_callback(unblock)
96+
97+
while not event.wait(1.0):
98+
if context.is_shutdown:
99+
self.__logger.warning(
100+
"Abandoning wait for the '{}' service response, due to shutdown.".format(
101+
self.__rclpy_change_state_client.srv_name),
102+
)
103+
response_future.cancel()
104+
return
105+
106+
if response_future.exception() is not None:
107+
raise response_future.exception()
108+
response = response_future.result()
109+
86110
if not response.success:
87111
self.__logger.error(
88112
"Failed to make transition '{}' for LifecycleNode '{}'".format(

0 commit comments

Comments
 (0)