Bug report
Steps to reproduce
- Start an asynchronous action execution through the gateway.
- Cancel it with
DELETE /apps/{app}/operations/{op}/executions/{id} under conditions where the CancelGoal response does not arrive within the gateway budget.
- Read the error body, then read the execution status the gateway reports.
Expected behavior
A timeout is reported as a timeout, and the gateway state agrees with the /_action/status stream it is already subscribed to.
Actual behavior
The gateway returns HTTP 400 with x-medkit-ros2-action-rejected, which states that the action server refused the cancellation. What actually happened is that no answer arrived in time. The goal may well have been accepted for cancellation.
The response shape gives it away: return_code: 0 with success: false is "no answer", not a rejection, and there is no distinct code for it.
On that path the gateway also leaves its tracked status untouched, while the /_action/status subscription already knows the real outcome. So the state the gateway reports and the state it has just received disagree, and nothing reconciles them.
Environment
- ros2_medkit version: 0.6.0 (main)
- ROS 2 distro: humble (observed), jazzy
- OS: Ubuntu 22.04 (CI container)
Additional information
Worth fixing together: report a timeout as a timeout, and reconcile the cancel outcome against the status stream rather than deciding it from the request future alone.
The cancel budget was raised from 5s to 15s as a stopgap while investigating this. That is not the fix. The measured round trip is around a millisecond in every configuration tried, including two pinned cores under load, a churning 125-node graph, and CycloneDDS, so a five second stall is a lost response rather than a tight budget. The likely underlying cause is tracked in #575.
Bug report
Steps to reproduce
DELETE /apps/{app}/operations/{op}/executions/{id}under conditions where the CancelGoal response does not arrive within the gateway budget.Expected behavior
A timeout is reported as a timeout, and the gateway state agrees with the
/_action/statusstream it is already subscribed to.Actual behavior
The gateway returns HTTP 400 with
x-medkit-ros2-action-rejected, which states that the action server refused the cancellation. What actually happened is that no answer arrived in time. The goal may well have been accepted for cancellation.The response shape gives it away:
return_code: 0withsuccess: falseis "no answer", not a rejection, and there is no distinct code for it.On that path the gateway also leaves its tracked status untouched, while the
/_action/statussubscription already knows the real outcome. So the state the gateway reports and the state it has just received disagree, and nothing reconciles them.Environment
Additional information
Worth fixing together: report a timeout as a timeout, and reconcile the cancel outcome against the status stream rather than deciding it from the request future alone.
The cancel budget was raised from 5s to 15s as a stopgap while investigating this. That is not the fix. The measured round trip is around a millisecond in every configuration tried, including two pinned cores under load, a churning 125-node graph, and CycloneDDS, so a five second stall is a lost response rather than a tight budget. The likely underlying cause is tracked in #575.