ROS 2 timer behavior when callbacks take longer than the timer period

I wrote a small test wrt. the behavior of ROS 2 timers in case of a timer callback that (always or occasionally) takes longer than the timer period, see this repository.

Posting here as I think it can be of relevance to others.

The conclusions:

Consider a timer at a rate of 1s,

  • The first callback call however takes 3s calculation time,
  • The next calls take only a few milliseconds.

In case of a mutually exclusive callback group:

  • The first call will be made at t = 1s,
  • This blocks execution of the 2nd call (obviously since mutually exclusive),
  • The 2nd call will start instantly after completion of the 1st call (i.e. at t = 4s),
  • The 3rd call will start at t = 5s,
  • The 4th call will start at t = 6s,
  • Etc.

This means that next intended callback time is defined as:
previous callback start time + timer period,
as otherwise calls 2, 3 and 4 would all be made asap after completion of call 1, and call 5 at t = 5s.
(this is not entirely correct; see clarification by @ottojo in next post)

In case of a reentrant callback group:

  • The first call is made at t = 1s, runs until t = 4s,
  • The 2nd call is started at t = 2s in another (available) thread,
  • The 3rd call is started at t = 3s also in an available thread,
  • Etc.

As long as there are enough available threads (and computing power), then it does not matter if the callbacks takes longer than the timer period, the callbacks will still be called at the correct rate.

However if the executor runs out of available threads, then similar behavior as in the mutually exclusive case is obtained (i.e. execution of the next call is blocked until a previous one is done).

6 Likes

Hi! I think previous callback start time + timer period as next callback time is a bit misleading.
If the callback duration is not an exact multiple of the timer period, the “phase” of subsequent invocations is not changed. I repeated your experiment, but the first callback takes 3.5 seconds instead of 3.
This diagram shows the timer executions:


As you can see, one callback runs directly after the first one, even if the time is not a multiple of one second. The next callback however runs at t=5, even though the duration since the last invocation is only 0.5s.
The way i have been thinking about is at most one "missed" callback is executed (timer events from t=2 and t=3 are discarded, t=4 was “missed” and runs as soon as possible, t=5 runs as usual)

5 Likes

@JRTG thanks for sharing the information.

Do you find any suggested behavior or problems with current behavior? Or just sharing the current behavior that you can find?

thanks,
Tomoya

@ottojo Thanks for the clarification!

@tomoyafujita No, I don’t have a specific issue. I just wanted to know what happens if some (or many) callbacks take longer than the timer period.

2 Likes

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.