From 9e080bf37563b1a6e9a0328a56c0ec3266dc3c77 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Tue, 6 Dec 2022 18:20:56 +0100 Subject: [PATCH] BUG/MINOR: checks: make sure fastinter is used even on forced transitions MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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. --- src/check.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/check.c b/src/check.c index e4f9756a34..0f5202898a 100644 --- a/src/check.c +++ b/src/check.c @@ -1138,8 +1138,21 @@ struct task *process_chk_conn(struct task *t, void *context, unsigned int state) 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 @@ struct task *process_chk_conn(struct task *t, void *context, unsigned int state) 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) { -- 2.39.5