rclpy icon indicating copy to clipboard operation
rclpy copied to clipboard

exception when listing parameters and there are two nodes with the same name

Open wjwwood opened this issue 7 years ago • 2 comments

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

wjwwood avatar Aug 22 '18 21:08 wjwwood

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)

tfoote avatar Sep 13 '18 19:09 tfoote