rmf-web取消任务时报错
rmf-web取消任务时报错
问题描述
在rem-web界面取消任务时,有时会产生错误信息,导致api-server崩溃。其主要错误信息如下:
[start:rmf-server] Exception in thread Thread-2:
[start:rmf-server] Traceback (most recent call last):
[start:rmf-server] File "/usrb/python3.8/threading.py", line 932, in _bootstrap_inner
[start:rmf-server] self.run()
[start:rmf-server] File "/usrb/python3.8/threading.py", line 870, in run
[start:rmf-server] self._target(*self._args, **self._kwargs)
[start:rmf-server] File "/home/rmf/rmf-web/packages/api-server/api_server/ros.py", line 53, in <lambda>
[start:rmf-server] _spin_thread = threading.Thread(target=lambda: rclpy.spin(_ros_node))
[start:rmf-server] File "/opt/ros/galacticb/python3.8/site-packages/rclpy/__init__.py", line 196, in spin
[start:rmf-server] executor.spin_once()
[start:rmf-server] File "/opt/ros/galacticb/python3.8/site-packages/rclpy/executors.py", line 712, in spin_once
[start:rmf-server] raise handler.exception()
[start:rmf-server] File "/opt/ros/galacticb/python3.8/site-packages/rclpy/task.py", line 239, in __call__
[start:rmf-server] self._handler.send(None)
[start:rmf-server] File "/opt/ros/galacticb/python3.8/site-packages/rclpy/executors.py", line 418, in handler
[start:rmf-server] await call_coroutine(entity, arg)
[start:rmf-server] File "/opt/ros/galacticb/python3.8/site-packages/rclpy/executors.py", line 343, in _execute_subscription
[start:rmf-server] await await_or_execute(sub.callback, msg)
[start:rmf-server] File "/opt/ros/galacticb/python3.8/site-packages/rclpy/executors.py", line 107, in await_or_execute
[start:rmf-server] return callback(*args)
[start:rmf-server] File "/home/rmf/rmf-web/packages/api-server/api_server/rmf_io/rmf_service.py", line 88, in _handle_response
[start:rmf-server] fut.set_result(msg.json_msg)
[start:rmf-server] asyncio.exceptions.InvalidStateError: invalid state
问题分析
经过测试,发现是future 在处理set_result时的msg.json_msg中不包含state的属性,导致线程崩溃。
例如,cancel任务时topicapi_task_response
上会收到如下两种具有相同request_id的消息:
其中一条msg的
json_msg
属性中并不包含state
字段导致意外。
解决方案
def _handle_response(self, msg: ApiResponse):
self._logger.info(f"got response '{msg.request_id}'")
self._logger.debug(msg)
fut = self._requests.get(msg.request_id)
if fut is None:
self._logger.warning(
f"Received response for unknown request id: {msg.request_id}"
)
return
print(msg.json_msg)
# 添加判断state是否存在,若不存在则无视该msg
json_msg_=json.loads(msg.json_msg)
if "state" not in json_msg_ :
print(" `json_ msgs_` has no `state` attribute")
return
fut.set_result(msg.json_msg)
遗留问题
产生两个相同request_id的msg的原因,暂时无法确定
在github上提交了这个bug的issue,得到回复https://github.com/open-rmf/rmf-web/pull/682
回复中说是超时太短,将其增加到 5 秒,
https://github.com/open-rmf/rmf_demos/blob/main/rmf_demos_fleet_adapter/rmf_demos_fleet_adapter/RobotClientAPI.py#L36