]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: channel: Use dedicated functions to deal with STREAMER flags
authorChristopher Faulet <cfaulet@haproxy.com>
Tue, 21 Nov 2023 06:51:45 +0000 (07:51 +0100)
committerChristopher Faulet <cfaulet@haproxy.com>
Wed, 6 Dec 2023 09:24:41 +0000 (10:24 +0100)
For now, CF_STREAMER and CF_STREAMER_FAST flags are set in sc_conn_recv()
function. The logic is moved in dedicated functions.

First, channel_check_idletimer() function is now responsible to check the
channel's last read date against the idle timer value to be sure the
producer is still streaming data. Otherwise, it removes STREAMER flags.

Then, channel_check_xfer() function is responsible to check amount of data
transferred avec a receive, to eventually update STREAMER flags.

In sc_conn_recv(), we now use these functions.

include/haproxy/channel.h
src/stconn.c

index 17dd75fba6f984be265d4996cfe09f468b75f7b4..1b5c8a06fad7b248f9a05f574bf3f6d17a3c603b 100644 (file)
@@ -818,6 +818,69 @@ static inline size_t channel_empty(const struct channel *chn)
        return (IS_HTX_STRM(chn) ? htx_is_empty(htxbuf(&chn->buf)) : c_empty(chn));
 }
 
+/* Check channel's last_read date against the idle timeer to verify the producer
+ * is still streaming data or not
+ */
+static inline void channel_check_idletimer(struct channel *chn)
+{
+       if ((chn->flags & (CF_STREAMER | CF_STREAMER_FAST)) && !co_data(chn) &&
+           global.tune.idle_timer &&
+           (unsigned short)(now_ms - chn->last_read) >= global.tune.idle_timer) {
+               /* The buffer was empty and nothing was transferred for more
+                * than one second. This was caused by a pause and not by
+                * congestion. Reset any streaming mode to reduce latency.
+                */
+               chn->xfer_small = 0;
+               chn->xfer_large = 0;
+               chn->flags &= ~(CF_STREAMER | CF_STREAMER_FAST);
+       }
+}
+
+/* Check amount of transferred data after a receive. If <xferred> is greater
+ * than 0, the <last_read> date is updated and STREAMER flags for the channels
+ * are verified.
+ */
+static inline void channel_check_xfer(struct channel *chn, size_t xferred)
+{
+       if (!xferred)
+               return;
+
+       if ((chn->flags & (CF_STREAMER | CF_STREAMER_FAST)) &&
+           (xferred <= c_size(chn) / 2)) {
+               chn->xfer_large = 0;
+               chn->xfer_small++;
+               if (chn->xfer_small >= 3) {
+                       /* we have read less than half of the buffer in
+                        * one pass, and this happened at least 3 times.
+                        * This is definitely not a streamer.
+                        */
+                       chn->flags &= ~(CF_STREAMER | CF_STREAMER_FAST);
+               }
+               else if (chn->xfer_small >= 2) {
+                       /* if the buffer has been at least half full twchne,
+                        * we receive faster than we send, so at least it
+                        * is not a "fast streamer".
+                        */
+                       chn->flags &= ~CF_STREAMER_FAST;
+               }
+       }
+       else if (!(chn->flags & CF_STREAMER_FAST) && (xferred >= channel_data_limit(chn))) {
+               /* we read a full buffer at once */
+               chn->xfer_small = 0;
+               chn->xfer_large++;
+               if (chn->xfer_large >= 3) {
+                       /* we call this buffer a fast streamer if it manages
+                        * to be filled in one call 3 consecutive times.
+                        */
+                       chn->flags |= (CF_STREAMER | CF_STREAMER_FAST);
+               }
+       }
+       else {
+               chn->xfer_small = 0;
+               chn->xfer_large = 0;
+       }
+       chn->last_read = now_ms;
+}
 
 /* Returns the amount of bytes that can be written over the input data at once,
  * including reserved space which may be overwritten. This is used by Lua to
index 63dd9bf1f3416e8012ffb4f66f7088bde490bb0d..b3aed9521f9e4c2cf900f0b4a615f1f426e5a0e6 100644 (file)
@@ -1251,17 +1251,7 @@ int sc_conn_recv(struct stconn *sc)
        /* prepare to detect if the mux needs more room */
        sc_ep_clr(sc, SE_FL_WANT_ROOM);
 
-       if ((ic->flags & (CF_STREAMER | CF_STREAMER_FAST)) && !co_data(ic) &&
-           global.tune.idle_timer &&
-           (unsigned short)(now_ms - ic->last_read) >= global.tune.idle_timer) {
-               /* The buffer was empty and nothing was transferred for more
-                * than one second. This was caused by a pause and not by
-                * congestion. Reset any streaming mode to reduce latency.
-                */
-               ic->xfer_small = 0;
-               ic->xfer_large = 0;
-               ic->flags &= ~(CF_STREAMER | CF_STREAMER_FAST);
-       }
+       channel_check_idletimer(ic);
 
 #if defined(USE_LINUX_SPLICE)
        /* Detect if the splicing is possible depending on the stream policy */
@@ -1447,41 +1437,7 @@ int sc_conn_recv(struct stconn *sc)
        if (!cur_read)
                se_have_no_more_data(sc->sedesc);
        else {
-               if ((ic->flags & (CF_STREAMER | CF_STREAMER_FAST)) &&
-                   (cur_read <= ic->buf.size / 2)) {
-                       ic->xfer_large = 0;
-                       ic->xfer_small++;
-                       if (ic->xfer_small >= 3) {
-                               /* we have read less than half of the buffer in
-                                * one pass, and this happened at least 3 times.
-                                * This is definitely not a streamer.
-                                */
-                               ic->flags &= ~(CF_STREAMER | CF_STREAMER_FAST);
-                       }
-                       else if (ic->xfer_small >= 2) {
-                               /* if the buffer has been at least half full twice,
-                                * we receive faster than we send, so at least it
-                                * is not a "fast streamer".
-                                */
-                               ic->flags &= ~CF_STREAMER_FAST;
-                       }
-               }
-               else if (!(ic->flags & CF_STREAMER_FAST) && (cur_read >= channel_data_limit(ic))) {
-                       /* we read a full buffer at once */
-                       ic->xfer_small = 0;
-                       ic->xfer_large++;
-                       if (ic->xfer_large >= 3) {
-                               /* we call this buffer a fast streamer if it manages
-                                * to be filled in one call 3 consecutive times.
-                                */
-                               ic->flags |= (CF_STREAMER | CF_STREAMER_FAST);
-                       }
-               }
-               else {
-                       ic->xfer_small = 0;
-                       ic->xfer_large = 0;
-               }
-               ic->last_read = now_ms;
+               channel_check_xfer(ic, cur_read);
                sc_ep_report_read_activity(sc);
        }