BUG/MINOR: checks: make sure fastinter is used even on forced transitions
Aurélien also found that while previous commit a56798ea4 ("BUG/MEDIUM:
checks: do not reschedule a possibly running task on state change")
addressed one specific case where the check's task had to be woken up
quickly, but it's not always sufficient as the check will not be
considered as expired regarding the fastinter yet.
Let's make sure we do consider this specific case to update the timer
based on the new state if the new value is shorter. This particularly
means that even if the timer is not expired yet during a wakeup when
nothing is in progress, we need to check if applying the currently
effective interval right now to the current date would expire earlier
than what is programmed, then the timer needs to be updated. I.e.
make sure we never miss fastinter during a state transition before
the end of the current period.
The approach is not pretty, but it forces to repass via the existing
block dedicated to updating the timer if the current one is expired
and the updated one would appear earlier.
This must be backported to 2.7 along with the commit above.
diff --git a/src/check.c b/src/check.c
index e4f9756..0f52028 100644
--- a/src/check.c
+++ b/src/check.c
@@ -1138,8 +1138,21 @@
TRACE_STATE("health-check state to purge", CHK_EV_TASK_WAKE, check);
}
else if (!(check->state & (CHK_ST_INPROGRESS))) {
- /* no check currently running */
+ /* no check currently running, but we might have been woken up
+ * before the timer's expiration to update it according to a
+ * new state (e.g. fastinter), in which case we'll reprogram
+ * the new timer.
+ */
if (!expired) /* woke up too early */ {
+ if (check->server) {
+ int new_exp = tick_add(now_ms, MS_TO_TICKS(srv_getinter(check)));
+
+ if (tick_is_expired(new_exp, t->expire)) {
+ TRACE_STATE("health-check was advanced", CHK_EV_TASK_WAKE, check);
+ goto update_timer;
+ }
+ }
+
TRACE_STATE("health-check wake up too early", CHK_EV_TASK_WAKE, check);
goto out_unlock;
}
@@ -1264,6 +1277,7 @@
check->state &= ~(CHK_ST_INPROGRESS|CHK_ST_IN_ALLOC|CHK_ST_OUT_ALLOC);
check->state |= CHK_ST_SLEEPING;
+ update_timer:
if (check->server) {
rv = 0;
if (global.spread_checks > 0) {