]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: stream: Simplify retries counter calculation
authorChristopher Faulet <cfaulet@haproxy.com>
Tue, 29 Mar 2022 14:08:44 +0000 (16:08 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Wed, 13 Apr 2022 13:10:14 +0000 (15:10 +0200)
The conn_retries counter was set to the max value and decremented at each
connection retry. Thus the counter reflected the number of retries left and
not the real number of retries. All calculations of redispatch or reporting
of number of retries experienced were made using subtracts from the
configured retries, which was complicated and didn't bring any benefit.

Now, this counter is set to 0 and incremented at each retry. We know we've
reached the maximum allowed connection retries by comparing it to the
configured value. In all other cases, we directly use the counter.

This patch should address the feature request #1608.

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

index 0fb5e7a8b987b6260fe56d8ec6a1e12546baa196..2b65ea0affb41a6f50608662a7b096d9c665e3ba 100644 (file)
@@ -139,7 +139,7 @@ struct stream {
        int16_t priority_class;         /* priority class of the stream for the pending queue */
        int32_t priority_offset;        /* priority offset of the stream for the pending queue */
 
-       int conn_retries;               /* number of connect retries left */
+       int conn_retries;               /* number of connect retries performed */
 
        struct list list;               /* position in the thread's streams list */
        struct mt_list by_srv;          /* position in server stream list */
index 93093f74e303d6250a8e98823ada393ea7d9b631..19832301466dcc939d1249e3032179cc5bba3857 100644 (file)
@@ -331,11 +331,9 @@ static inline void stream_choose_redispatch(struct stream *s)
            (s->be->options & PR_O_REDISP) && !(s->flags & SF_FORCE_PRST) &&
            ((__objt_server(s->target)->cur_state < SRV_ST_RUNNING) ||
             (((s->be->redispatch_after > 0) &&
-              ((s->be->conn_retries - s->conn_retries) %
-               s->be->redispatch_after == 0)) ||
+              (s->conn_retries % s->be->redispatch_after == 0)) ||
              ((s->be->redispatch_after < 0) &&
-              ((s->be->conn_retries - s->conn_retries) %
-               (s->be->conn_retries + 1 + s->be->redispatch_after) == 0))) ||
+              (s->conn_retries % (s->be->conn_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_RR)))) {
                sess_change_server(s, NULL);
index d2d04d986f6ad7597370ae2af75e0cb4c6224b04..c73b23e7858de9566c4c127feaf45769b4b8d9f1 100644 (file)
@@ -1720,8 +1720,7 @@ skip_reuse:
             * it's our first try
             */
            ((cli_conn->flags & CO_FL_EARLY_DATA) ||
-            ((s->be->retry_type & PR_RE_EARLY_ERROR) &&
-             s->conn_retries == s->be->conn_retries)) &&
+            ((s->be->retry_type & PR_RE_EARLY_ERROR) && !s->conn_retries)) &&
            !channel_is_empty(cs_oc(s->csb)) &&
            srv_conn->flags & CO_FL_SSL_WAIT_HS)
                srv_conn->flags &= ~(CO_FL_SSL_WAIT_HS | CO_FL_WAIT_L6_CONN);
@@ -2222,6 +2221,8 @@ void back_handle_st_cer(struct stream *s)
        cs->si->exp    = TICK_ETERNITY;
        cs->si->flags &= ~SI_FL_EXP;
 
+       s->conn_retries++;
+
        /* we probably have to release last stream from the server */
        if (objt_server(s->target)) {
                struct connection *conn = cs_conn(cs);
@@ -2251,14 +2252,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 = 0;
+                       s->conn_retries = s->be->conn_retries;
                        DBG_TRACE_DEVEL("Bad SSL cert, disable connection retries", STRM_EV_STRM_PROC|STRM_EV_SI_ST|STRM_EV_STRM_ERR, s);
                }
        }
 
        /* ensure that we have enough retries left */
-       s->conn_retries--;
-       if (s->conn_retries < 0 || !(s->be->retry_type & PR_RE_CONN_FAILED)) {
+       if (s->conn_retries >= s->be->conn_retries || !(s->be->retry_type & PR_RE_CONN_FAILED)) {
                if (!cs->si->err_type) {
                        cs->si->err_type = SI_ET_CONN_ERR;
                }
index 7a72a06773b3aee186d1b1a18eec431f20d889be..2c93edbd205a324652f6e878d2a9b75f3290d00e 100644 (file)
@@ -1226,8 +1226,8 @@ static __inline int do_l7_retry(struct stream *s, struct stream_interface *si)
        struct channel *req, *res;
        int co_data;
 
-       s->conn_retries--;
-       if (s->conn_retries < 0)
+       s->conn_retries++;
+       if (s->conn_retries >= s->be->conn_retries)
                return -1;
 
        if (objt_server(s->target)) {
index c3b7d92bafbc08e33b8ca01c2c91126b3f0e9b62..edffcbdb75dbe01e1586e37ca514facd07bf8894 100644 (file)
--- a/src/log.c
+++ b/src/log.c
@@ -2616,10 +2616,7 @@ int sess_build_logline(struct session *sess, struct stream *s, char *dst, size_t
                        case LOG_FMT_RETRIES:  // %rq
                                if (s_flags & SF_REDISP)
                                        LOGCHAR('+');
-                               ret = ltoa_o(((s && s->conn_retries > 0)
-                                             ? (be->conn_retries - s->conn_retries)
-                                             : ((s && cs_si(s->csb)->state != SI_ST_INI) ? be->conn_retries : 0)),
-                                            tmplog, dst + maxsize - tmplog);
+                               ret = ltoa_o((s  ? s->conn_retries : 0), tmplog, dst + maxsize - tmplog);
                                if (ret == NULL)
                                        goto out;
                                tmplog = ret;
index 71460fe87a872859973838c15304d0a55b985b68..200f69efd770b305736a8319dd2116e2ce290786 100644 (file)
@@ -2161,7 +2161,7 @@ struct task *process_stream(struct task *t, void *context, unsigned int state)
                                 * perform a connection request.
                                 */
                                si_b->state = SI_ST_REQ; /* new connection requested */
-                               s->conn_retries = s->be->conn_retries;
+                               s->conn_retries = 0;
                                if ((s->be->retry_type &~ PR_RE_CONN_FAILED) &&
                                    (s->be->mode == PR_MODE_HTTP) &&
                                    !(s->txn->flags & TX_D_L7_RETRY))