Skip to content

Single-threaded executor can be starved by timers #392

@dhood

Description

@dhood

Context (comes from ros2/demos#187): A single-threaded executor has a timer scheduled for every N seconds, and also a service server.

Bug: If the timer callback takes >=N seconds to complete, the executor will never process service requests once the timer is triggered for the first time.

This is because of the combination of the following:

  1. When the spinning executor calls to get_next_executable, it does not call rcl_wait since the timer's ready, so the service is not marked as ready.
  2. Even if you force get_next_executable to always call wait_for_work so the server can get receive its request, the server will still not get processed by the executor because the timer will always get chosen first as the next_ready_executable.

Forcing get_next_executable to always call wait_for_work and giving timers lower priority in get_next_ready_executable will fix this situation, but it is inefficient to wait when it's not necessary, and I'm not sure checking timers last is a fix-all (could there be a parallel situation when the server needs to be the lowest priority?).

@dirk-thomas mentioned that a queue of some sort is probably more appropriate, so that get_next_executable processes events in the order that they were received.

For now, we have to recommend that users not permit timer callbacks to block for longer than the duration at which they're scheduled (this might be in our documentation somewhere already?).

Metadata

Metadata

Assignees

Labels

bugSomething isn't workinghitlistreadyWork is about to start (Kanban column)

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions