]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: applet: make the call_rate only count the no-progress calls
authorWilly Tarreau <w@1wt.eu>
Tue, 19 Jul 2022 18:36:15 +0000 (20:36 +0200)
committerWilly Tarreau <w@1wt.eu>
Tue, 23 Aug 2022 18:19:11 +0000 (20:19 +0200)
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.

src/applet.c

index 197140fb87dfe03bc45534d684ca33b5ac978de5..fedd05c5782aaa48f9a9a93328eb18fafe18f372 100644 (file)
@@ -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);