Skip to content

Commit

Permalink
Make service lients context-aware. (#1295)
Browse files Browse the repository at this point in the history
This way it is much easier to create examples that properly
clean up after themselves.

Signed-off-by: Chris Lalancette <[email protected]>
  • Loading branch information
clalancette authored Jun 4, 2024
1 parent b49ceff commit 88ce194
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 0 deletions.
13 changes: 13 additions & 0 deletions rclpy/rclpy/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@

import threading
import time
from types import TracebackType
from typing import Dict
from typing import Optional
from typing import Type
from typing import TypeVar

from rclpy.callback_groups import CallbackGroup
Expand Down Expand Up @@ -224,3 +226,14 @@ def destroy(self):
should call :meth:`.Node.destroy_client`.
"""
self.__client.destroy_when_not_in_use()

def __enter__(self) -> 'Client':
return self

def __exit__(
self,
exc_type: Optional[Type[BaseException]],
exc_val: Optional[BaseException],
exc_tb: Optional[TracebackType],
) -> None:
self.destroy()
16 changes: 16 additions & 0 deletions rclpy/test/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,22 @@ def _service(request, response):
self.node.destroy_client(cli)
self.node.destroy_service(srv)

def test_sync_call_context_manager(self):
def _service(request, response):
return response
with self.node.create_client(GetParameters, 'get/parameters') as cli:
with self.node.create_service(GetParameters, 'get/parameters', _service):
self.assertTrue(cli.wait_for_service(timeout_sec=20))
executor = rclpy.executors.SingleThreadedExecutor(context=self.context)
executor.add_node(self.node)
executor_thread = threading.Thread(
target=TestClient._spin_rclpy_node, args=(self.node, executor))
executor_thread.start()
result = cli.call(GetParameters.Request(), 0.5)
self.assertTrue(result is not None)
executor.shutdown()
executor_thread.join()


if __name__ == '__main__':
unittest.main()

0 comments on commit 88ce194

Please sign in to comment.