|
15 | 15 | """Module for the LifecycleNode action.""" |
16 | 16 |
|
17 | 17 | import functools |
| 18 | +import threading |
18 | 19 | from typing import cast |
19 | 20 | from typing import List |
20 | 21 | from typing import Optional |
@@ -77,12 +78,35 @@ def _on_transition_event(self, context, msg): |
77 | 78 | def _call_change_state(self, request, context: launch.LaunchContext): |
78 | 79 | while not self.__rclpy_change_state_client.wait_for_service(timeout_sec=1.0): |
79 | 80 | if context.is_shutdown: |
80 | | - self.___logger.warning( |
| 81 | + self.__logger.warning( |
81 | 82 | "Abandoning wait for the '{}' service, due to shutdown.".format( |
82 | 83 | self.__rclpy_change_state_client.srv_name), |
83 | 84 | ) |
84 | 85 | 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 | + |
86 | 110 | if not response.success: |
87 | 111 | self.__logger.error( |
88 | 112 | "Failed to make transition '{}' for LifecycleNode '{}'".format( |
|
0 commit comments