Skip loop delay if new goal is already available #212
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
There is a bug in
SimpleActionClient
that causes unnecessary delays of 0.1s if goals are sent in quick succession and the action server status is not set at the very end of theexecute_callback
.Steps to Reproduce
Expected behavior
The time required to process 10 goals is ~0.1 seconds.
Actual behavior
The time required to process 10 goals is ~1.0 seconds.
Implications
This behavior can cause unnecessary delays when processing a queue of actions. Even though the delay per goal is only 0.1 seconds, this can stack up quickly when the queue is longer.
Cause
The
self.execute_condition.wait(loop_duration.to_sec())
statement inSimpleActionServer.executeLoop()
starts athreading.Condition
that waits until it is interrupted (notified) or until it reaches the specified timeout of 0.1 seconds. The notification is triggered in theSimpleActionServer.internal_goal_callback()
whenever a new goal is received.In the example case, the action is
set_succeeded()
slightly before the callback is exited. The client is therefore able to send the next goal while the server is still processing theexecute_callback
of the previous one. The new goal is received before entering theexecute_condition.wait()
, and the interrupt/notification is triggered with no effect. When exiting theexecute_callback
and entering theexecute_condition.wait()
, there is nothing to interrupt the lock because the new goal is already here. The lock therefore waits until its full timeout before looping around and explicitly checking for goal presence.Solution
Start the
execute_condition.wait()
only if a new goal is not already present. Check for goal presence after acquiring theexecute_condition
lock to ensure thenew_goal
flag can not be changed by the other thread during/after checking.