]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: stream: Rely on a per-stream max connection retries value
authorChristopher Faulet <cfaulet@haproxy.com>
Wed, 25 Sep 2024 13:05:07 +0000 (15:05 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Mon, 30 Sep 2024 14:55:53 +0000 (16:55 +0200)
Instead of directly relying on the backend parameter to limit the number of
connection retries, we now use a per-stream value. This value is by default
inherited from the backend value when it is set. So for now, there is no
change except the stream value is used instead of the backend value. But
thanks to this change, it will be possible to dynamically change this value.

include/haproxy/stream-t.h
include/haproxy/stream.h
src/backend.c
src/http_ana.c
src/stream.c

index 91ef26c5c6b47dd32b15295095d5abc5c533f298..43353c367fb708de6bc9a2b4ea2b7f8eaf4f144f 100644 (file)
@@ -234,6 +234,7 @@ struct stream {
                                         * This is a bit field of TASK_WOKEN_* */
        int conn_retries;               /* number of connect retries performed */
        unsigned int conn_exp;          /* wake up time for connect, queue, turn-around, ... */
+       unsigned int max_retries;     /* Maximum number of connection retried (=0 is backend is not set) */
        unsigned int conn_err_type;     /* first error detected, one of STRM_ET_* */
 
        struct stream *parent;          /* Pointer to the parent stream, if any. NULL most of time */
index e806a2a6f09e260b3e55601ec490c96b06cbd2dd..308fb6904766b289c27ed944b53866565f1a526d 100644 (file)
@@ -350,7 +350,7 @@ static inline void stream_choose_redispatch(struct stream *s)
             (((s->be->redispatch_after > 0) &&
               (s->conn_retries % s->be->redispatch_after == 0)) ||
              ((s->be->redispatch_after < 0) &&
-              (s->conn_retries % (s->be->conn_retries + 1 + s->be->redispatch_after) == 0))) ||
+              (s->conn_retries % (s->max_retries + 1 + s->be->redispatch_after) == 0))) ||
             (!(s->flags & SF_DIRECT) && s->be->srv_act > 1 &&
              ((s->be->lbprm.algo & BE_LB_KIND) != BE_LB_KIND_HI)))) {
                sess_change_server(s, NULL);
index e4bd465e9818439a778127413af0c6d9df517c3b..b2f924c278bd684e2544820570496fcb854e4168 100644 (file)
@@ -1324,7 +1324,7 @@ static int do_connect_server(struct stream *s, struct connection *conn)
 
        if (co_data(&s->res))
                conn_flags |= CONNECT_HAS_DATA;
-       if (s->conn_retries == s->be->conn_retries)
+       if (s->conn_retries == s->max_retries)
                conn_flags |= CONNECT_CAN_USE_TFO;
        if (!conn_ctrl_ready(conn) || !conn_xprt_ready(conn)) {
                ret = conn->ctrl->connect(conn, conn_flags);
@@ -2402,13 +2402,13 @@ void back_handle_st_cer(struct stream *s)
                         * provided by the client and we don't want to let the
                         * client provoke retries.
                         */
-                       s->conn_retries = s->be->conn_retries;
+                       s->conn_retries = s->max_retries;
                        DBG_TRACE_DEVEL("Bad SSL cert, disable connection retries", STRM_EV_STRM_PROC|STRM_EV_CS_ST|STRM_EV_STRM_ERR, s);
                }
        }
 
        /* ensure that we have enough retries left */
-       if (s->conn_retries >= s->be->conn_retries || !(s->be->retry_type & PR_RE_CONN_FAILED)) {
+       if (s->conn_retries >= s->max_retries || !(s->be->retry_type & PR_RE_CONN_FAILED)) {
                if (!s->conn_err_type) {
                        s->conn_err_type = STRM_ET_CONN_ERR;
                }
index a8d1b18fc37e3092b5a5028a31d6b69e06e1a754..d132e5de26eb4992658bb9824c9602619ea9cec4 100644 (file)
@@ -1142,7 +1142,7 @@ static __inline int do_l7_retry(struct stream *s, struct stconn *sc)
        struct channel *req, *res;
        int co_data;
 
-       if (s->conn_retries >= s->be->conn_retries)
+       if (s->conn_retries >= s->max_retries)
                return -1;
        s->conn_retries++;
        if (objt_server(s->target)) {
index f689edd768ec5f885a9e7a830917236ae671efe8..d0623a9adbcbdc8ef2eaa761d14e141b25f7e31c 100644 (file)
@@ -430,7 +430,7 @@ struct stream *stream_new(struct session *sess, struct stconn *sc, struct buffer
 
        s->task = t;
        s->pending_events = 0;
-       s->conn_retries = 0;
+       s->conn_retries = s->max_retries = 0;
        s->conn_exp = TICK_ETERNITY;
        s->conn_err_type = STRM_ET_NONE;
        s->prev_conn_state = SC_ST_INI;
@@ -1123,6 +1123,9 @@ static int process_switching_rules(struct stream *s, struct channel *req, int an
 
        }
 
+       /* Se the max connection retries for the stream. */
+       s->max_retries = s->be->conn_retries;
+
        /* we don't want to run the TCP or HTTP filters again if the backend has not changed */
        if (fe == s->be) {
                s->req.analysers &= ~AN_REQ_INSPECT_BE;