-
Notifications
You must be signed in to change notification settings - Fork 496
Fix expiration of action goals when EventsExecutors are used #3018
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: rolling
Are you sure you want to change the base?
Fix expiration of action goals when EventsExecutors are used #3018
Conversation
Signed-off-by: Skyler Medeiros <skye.galaxy@proton.me>
Signed-off-by: Skyler Medeiros <skye.galaxy@proton.me>
Signed-off-by: Skyler Medeiros <skye.galaxy@proton.me>
mjcarroll
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! Overall, looks pretty good and solves the memory leak.
I have a few thoughts/concerns that we should take a look at before merging.
Signed-off-by: Skyler Medeiros <skye.galaxy@proton.me>
Signed-off-by: Skyler Medeiros <skye.galaxy@proton.me>
Signed-off-by: Skyler Medeiros <skye.galaxy@proton.me>
fujitatomoya
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the other major downside for Non EventExecutors is that it now calls execute_check_expired_goals twice on each expiration? once from the timer callback (which is added by this PR) and the another from the waitable's execute() call?
|
Hm, we could add 'rcl_action_server_set_expired_callback' and handle this in the rcl layer to only call the callback if the timer expires etc. |
Signed-off-by: Skyler Medeiros <skye.galaxy@proton.me>
|
Something else to consider: If this leak's still happening for C++ based EventsExecutors, the coupling of goal expiration to the waitset implies that this could also be happening with the rclpy EventsExecutor. I'm not finding any analogous changes on the rclpy side to expire goals from a timer that isn't still using the waitset to check if it's expired. Also, I've verified that this leak is also present in Kilted and whatever solution we arrive at will ultimately need to be backported. |
Description
In the long actions ram usage section of the benchmarks iRobot shared back in September 2025, there was a memory leak identified in rolling for both the EventsExecutor implementations. I did some deeper profiling and found that it was the result of expired goal results never being cleared out.
This PR introduces a small change which ensures
execute_check_expire_goals()is actually called within theexpire_timer_callback for actions. I've also added a test torclcpp_action/test_server.cppwhich validates that expired goals are properly cleared out if the events executor is used.Because the events executors have a slightly different execution path for waitables than the waitset based executors (we call
take_data_by_entity_id()directly instead oftake_data()),is_ready()seems to be the only function capable of emitting anExpiredentity if theexpire_timer_was triggered, butis_ready()is currently coupled with the use of waitsets.Followup to #2699.
Alternative to #3012
Is this user-facing behavior change?
Properly fixes a memory leak in actions where goal handles are stored indefinitely and never expired if using the EventsExecutor.
Did you use Generative AI?
No
Additional Information
EventsExecutor heaptrack allocation profile of irobot benchmark using 1MB payload, before:

after:
