]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: stream: Try to use a small buffer for HTTP request on queuing
authorChristopher Faulet <cfaulet@haproxy.com>
Mon, 9 Mar 2026 17:10:17 +0000 (18:10 +0100)
committerChristopher Faulet <cfaulet@haproxy.com>
Mon, 23 Mar 2026 13:02:42 +0000 (14:02 +0100)
When a HTX stream is queued, if the request is small enough, it is moved
into a small buffer. This should save memory on instances intensively using
queues.

Applet and connection receive function were update to block receive when a
small buffer is in use.

src/stconn.c
src/stream.c

index 8d5dfeade6eee541422fc777f7d2870376090a96..1aa136affe70368bfc06c5306d1aff8b08986923 100644 (file)
@@ -1190,7 +1190,7 @@ int sc_conn_recv(struct stconn *sc)
                 * SE_FL_RCV_MORE on the SC if more space is needed.
                 */
                max = channel_recv_max(ic);
-               if ((ic->flags & CF_WROTE_DATA) && b_is_large(sc_ib(sc)))
+               if (b_is_small(sc_ib(sc)) || ((ic->flags & CF_WROTE_DATA) && b_is_large(sc_ib(sc))))
                        max = 0;
                ret = CALL_MUX_WITH_RET(conn->mux, rcv_buf(sc, &ic->buf, max, cur_flags));
 
@@ -1861,7 +1861,7 @@ int sc_applet_recv(struct stconn *sc)
         * SE_FL_RCV_MORE on the SC if more space is needed.
         */
        max = channel_recv_max(ic);
-       if ((ic->flags & CF_WROTE_DATA) && b_is_large(sc_ib(sc)))
+       if (b_is_small(sc_ib(sc)) || ((ic->flags & CF_WROTE_DATA) && b_is_large(sc_ib(sc))))
                max = 0;
        ret = appctx_rcv_buf(sc, &ic->buf, max, flags);
        if (sc_ep_test(sc, SE_FL_WANT_ROOM)) {
index cb26fb68c37817e5ce716b1e763ad712d425824a..28989bd2f35ddeadf354270efb35887348fb533d 100644 (file)
@@ -2511,6 +2511,18 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
                        srv = objt_server(s->target);
                        if (scb->state == SC_ST_ASS && srv && srv->rdr_len && (s->flags & SF_REDIRECTABLE))
                                http_perform_server_redirect(s, scb);
+
+                       if (unlikely(scb->state == SC_ST_QUE && IS_HTX_STRM(s))) {
+                               struct buffer sbuf = BUF_NULL;
+
+                               if (!htx_move_to_small_buffer(&sbuf, &req->buf))
+                                       break;
+                               b_free(&req->buf);
+                               offer_buffers(s, 1);
+                               req->buf = sbuf;
+                               DBG_TRACE_DEVEL("request moved to a small buffer", STRM_EV_STRM_PROC, s);
+                       }
+
                } while (scb->state == SC_ST_ASS);
        }