From: Willy Tarreau Date: Tue, 19 Jul 2022 18:36:15 +0000 (+0200) Subject: BUG/MINOR: applet: make the call_rate only count the no-progress calls X-Git-Tag: v2.7-dev5~69 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=df3cab1ca176a372908764de28b5273cbe6c4e61;p=thirdparty%2Fhaproxy.git BUG/MINOR: applet: make the call_rate only count the no-progress calls This is very similar to what we did in commit 6c539c4b8 ("BUG/MINOR: stream: make the call_rate only count the no-progress calls"), it's better to only count the call rate with no progress than to count all calls and try to figure if there's no progress, because a fast running applet might once satisfy the whole condition and trigger the bug. This typically happens when artificially limiting the number of messages sent at once by an applet, but could happen with plenty of highly interactive applets. This patch could be backported to stable versions if there are any indications that it might be useful there. --- diff --git a/src/applet.c b/src/applet.c index 197140fb87..fedd05c578 100644 --- a/src/applet.c +++ b/src/applet.c @@ -253,14 +253,14 @@ struct task *task_run_applet(struct task *t, void *context, unsigned int state) } /* measure the call rate and check for anomalies when too high */ - rate = update_freq_ctr(&app->call_rate, 1); - if (rate >= 100000 && app->call_rate.prev_ctr && // looped more than 100k times over last second - ((b_size(sc_ib(sc)) && sc->flags & SC_FL_NEED_BUFF) || // asks for a buffer which is present + if (((b_size(sc_ib(sc)) && sc->flags & SC_FL_NEED_BUFF) || // asks for a buffer which is present (b_size(sc_ib(sc)) && !b_data(sc_ib(sc)) && sc->flags & SC_FL_NEED_ROOM) || // asks for room in an empty buffer (b_data(sc_ob(sc)) && sc_is_send_allowed(sc)) || // asks for data already present (!b_data(sc_ib(sc)) && b_data(sc_ob(sc)) && // didn't return anything ... (sc_oc(sc)->flags & (CF_WRITE_PARTIAL|CF_SHUTW_NOW)) == CF_SHUTW_NOW))) { // ... and left data pending after a shut - stream_dump_and_crash(&app->obj_type, read_freq_ctr(&app->call_rate)); + rate = update_freq_ctr(&app->call_rate, 1); + if (rate >= 100000 && app->call_rate.prev_ctr) // looped like this more than 100k times over last second + stream_dump_and_crash(&app->obj_type, read_freq_ctr(&app->call_rate)); } sc->app_ops->wake(sc);