exception when listing parameters and there are two nodes with the same name
Bug report
Required Info:
- Operating System:
- macOS
- Installation type:
- bouncy patch 2 rc
- DDS implementation:
- Fast-RTPS
- Client library (if applicable):
- rclpy
Steps to reproduce issue
% ros2 run demo_nodes_cpp listener &
% ros2 run demo_nodes_cpp listener &
% ros2 param set listener foo.bar.baz True
...
% ros2 param list
...
Expected behavior
Some times the last command will return:
% ros2 param list
listener:
foo.bar.baz
Actual behavior
Some times the last command will return:
% ros2 param list
Traceback (most recent call last):
File "/tmp/ros2-osx/bin/ros2", line 11, in <module>
load_entry_point('ros2cli==0.5.4', 'console_scripts', 'ros2')()
File "/tmp/ros2-osx/lib/python3.7/site-packages/ros2cli/cli.py", line 69, in main
rc = extension.main(parser=parser, args=args)
File "/tmp/ros2-osx/lib/python3.7/site-packages/ros2param/command/param.py", line 40, in main
return extension.main(args=args)
File "/tmp/ros2-osx/lib/python3.7/site-packages/ros2param/verb/list.py", line 81, in main
rclpy.spin_until_future_complete(node, futures[node_name])
File "/tmp/ros2-osx/lib/python3.7/site-packages/rclpy/__init__.py", line 126, in spin_until_future_complete
executor.spin_until_future_complete(future)
File "/tmp/ros2-osx/lib/python3.7/site-packages/rclpy/executors.py", line 218, in spin_until_future_complete
self.spin_once()
File "/tmp/ros2-osx/lib/python3.7/site-packages/rclpy/executors.py", line 528, in spin_once
raise handler.exception()
File "/tmp/ros2-osx/lib/python3.7/site-packages/rclpy/task.py", line 206, in __call__
self._handler.send(None)
File "/tmp/ros2-osx/lib/python3.7/site-packages/rclpy/executors.py", line 308, in handler
await call_coroutine(entity, arg)
File "/tmp/ros2-osx/lib/python3.7/site-packages/rclpy/executors.py", line 253, in _execute_client
future = client._pending_requests[sequence]
KeyError: 1
Additional information
I think this is a violation of the assumption that nodes have unique names (violated by running listener twice without renaming at least one of them), but this error in the executor could probably be made more robust and/or informative.
Separately, this underscores the need to resolve the node name uniqueness issue, see: https://github.com/ros2/design/issues/187
I've debugged into this but haven't found the root cause yet. I believe @wjwwood's speculation that it's coming from the duplicately named nodes is correct, but haven't found the code path for the collision.
Digging through the call stack and tracing the values back up here are my notes so far.
KeyError:1 https://github.com/ros2/rclpy/blob/62012d3650de790d89c725232451c4e998b396fb/rclpy/rclpy/executors.py#L255 future = client._pending_requests[sequence]
sequence is 1 expects 0
Callig coroutine
https://github.com/ros2/rclpy/blob/master/rclpy/rclpy/executors.py#L310
await call_coroutine(entity, arg)
arg comes from
https://github.com/ros2/rclpy/blob/62012d3650de790d89c725232451c4e998b396fb/rclpy/rclpy/executors.py#L303 arg = take_from_wait_list(entity)
_make_request
take_from_wait_list is invocation of
https://github.com/ros2/rclpy/blob/62012d3650de790d89c725232451c4e998b396fb/rclpy/rclpy/executors.py#L263
Which calls through to the CAPI
https://github.com/ros2/rclpy/blob/62012d3650de790d89c725232451c4e998b396fb/rclpy/src/rclpy/_rclpy.c#L2504
/// Take a request from a given service
/**
* Raises ValueError if pyservice is not a service capsule
*
* \param[in] pyservice Capsule pointing to the service to process the request
* \param[in] pyrequest_type Instance of the message type to take
* \return List with 2 elements:
* first element: a Python request message with all fields populated with received request
* second element: a Capsule pointing to the header (rmw_request_id) of the processed request
*/
static PyObject *
rclpy_take_request(PyObject * Py_UNUSED(self), PyObject * args)