]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: server: Factorize code to deal with reuse of server idle connections
authorChristopher Faulet <cfaulet@haproxy.com>
Thu, 2 Jul 2020 13:45:56 +0000 (15:45 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Wed, 15 Jul 2020 12:08:14 +0000 (14:08 +0200)
The srv_use_idle_conn() function is now responsible to update the server
counters and the connection flags when an idle connection is reused. The same
function is called when a new connection is created. This simplifies a bit the
connect_server() function.

include/haproxy/connection.h
include/haproxy/server.h
src/backend.c
src/tcpcheck.c

index 094e54cde1dd09d3507de050673d820192132c02..08f4313fe0861b5560d4c532714f1b48fd39e77e 100644 (file)
@@ -393,8 +393,11 @@ static inline struct connection *conn_new(void *target)
        struct connection *conn;
 
        conn = pool_alloc(pool_head_connection);
-       if (likely(conn != NULL))
+       if (likely(conn != NULL)) {
                conn_init(conn, target);
+               if (obj_type(target) == OBJ_TYPE_SERVER)
+                       srv_use_idle_conn(__objt_server(target), conn);
+       }
        return conn;
 }
 
index 3ad60d0cde12fcebe321fe5ac64da041cd60ee3c..929eeba6f0edf2bbb232af33243e025dbb1103ff 100644 (file)
@@ -239,6 +239,30 @@ static inline enum srv_initaddr srv_get_next_initaddr(unsigned int *list)
        return ret;
 }
 
+static inline void srv_use_idle_conn(struct server *srv, struct connection *conn)
+{
+       if (conn->flags & CO_FL_LIST_MASK) {
+               conn->idle_time = 0;
+               _HA_ATOMIC_SUB(&srv->curr_idle_conns, 1);
+               _HA_ATOMIC_SUB(conn->flags & CO_FL_SAFE_LIST ? &srv->curr_safe_nb : &srv->curr_idle_nb, 1);
+               _HA_ATOMIC_SUB(&srv->curr_idle_thr[tid], 1);
+               conn->flags &= ~CO_FL_LIST_MASK;
+               __ha_barrier_atomic_store();
+               LIST_ADDQ(&srv->available_conns[tid], mt_list_to_list(&conn->list));
+       }
+
+       _HA_ATOMIC_ADD(&srv->curr_used_conns, 1);
+
+       /* It's ok not to do that atomically, we don't need an
+        * exact max.
+        */
+       if (srv->max_used_conns < srv->curr_used_conns)
+               srv->max_used_conns = srv->curr_used_conns;
+
+       if (srv->est_need_conns < srv->curr_used_conns)
+               srv->est_need_conns = srv->curr_used_conns;
+}
+
 /* This adds an idle connection to the server's list if the connection is
  * reusable, not held by any owner anymore, but still has available streams.
  */
index 47f4bffb5d9276935a9e152fce25acff4a905d73..372389aae2a572d9846b24880a70d50ef2798b76 100644 (file)
@@ -1166,13 +1166,8 @@ static struct connection *conn_backend_get(struct server *srv, int is_safe)
                conn = NULL;
  done:
        if (conn) {
-               conn->idle_time = 0;
                _HA_ATOMIC_STORE(&srv->next_takeover, (i + 1 == global.nbthread) ? 0 : i + 1);
-               _HA_ATOMIC_SUB(&srv->curr_idle_conns, 1);
-               _HA_ATOMIC_SUB(&srv->curr_idle_thr[i], 1);
-               _HA_ATOMIC_SUB(is_safe ? &srv->curr_safe_nb : &srv->curr_idle_nb, 1);
-               __ha_barrier_atomic_store();
-               LIST_ADDQ(&srv->available_conns[tid], mt_list_to_list(&conn->list));
+               srv_use_idle_conn(srv, conn);
        }
        return conn;
 }
@@ -1201,7 +1196,6 @@ int connect_server(struct stream *s)
        int reuse = 0;
        int init_mux = 0;
        int err;
-       int was_unused = 0;
 
 
        /* This will catch some corner cases such as lying connections resulting from
@@ -1251,20 +1245,17 @@ int connect_server(struct stream *s)
                                 * try idle then safe.
                                 */
                                srv_conn = conn_backend_get(srv, 0);
-                               was_unused = 1;
                        }
                        else if (srv->safe_conns &&
                                 ((s->txn && (s->txn->flags & TX_NOT_FIRST)) ||
                                  (s->be->options & PR_O_REUSE_MASK) >= PR_O_REUSE_AGGR) &&
                                 srv->curr_safe_nb > 0) {
                                srv_conn = conn_backend_get(srv, 1);
-                               was_unused = 1;
                        }
                        else if (srv->idle_conns &&
                                 ((s->be->options & PR_O_REUSE_MASK) == PR_O_REUSE_ALWS) &&
                                 srv->curr_idle_nb > 0) {
                                srv_conn = conn_backend_get(srv, 0);
-                               was_unused = 1;
                        }
                        /* If we've picked a connection from the pool, we now have to
                         * detach it. We may have to get rid of the previous idle
@@ -1272,10 +1263,8 @@ int connect_server(struct stream *s)
                         * other owner's. That way it may remain alive for others to
                         * pick.
                         */
-                       if (srv_conn) {
+                       if (srv_conn)
                                reuse = 1;
-                               srv_conn->flags &= ~CO_FL_LIST_MASK;
-                       }
                }
        }
 
@@ -1369,7 +1358,6 @@ int connect_server(struct stream *s)
        /* no reuse or failed to reuse the connection above, pick a new one */
        if (!srv_conn) {
                srv_conn = conn_new(s->target);
-               was_unused = 1;
                srv_cs = NULL;
 
                srv_conn->owner = s->sess;
@@ -1377,17 +1365,6 @@ int connect_server(struct stream *s)
                        conn_set_private(srv_conn);
        }
 
-       if (srv_conn && srv && was_unused) {
-               _HA_ATOMIC_ADD(&srv->curr_used_conns, 1);
-               /* It's ok not to do that atomically, we don't need an
-                * exact max.
-                */
-               if (srv->max_used_conns < srv->curr_used_conns)
-                       srv->max_used_conns = srv->curr_used_conns;
-
-               if (srv->est_need_conns < srv->curr_used_conns)
-                       srv->est_need_conns = srv->curr_used_conns;
-       }
        if (!srv_conn || !sockaddr_alloc(&srv_conn->dst)) {
                if (srv_conn)
                        conn_free(srv_conn);
index 6f962cc6b61a564877386fc6fcc7cae85db76055..e83b915b9cad6aa8b472947e01445ba7fc4adb12 100644 (file)
@@ -1026,9 +1026,6 @@ enum tcpcheck_eval_ret tcpcheck_eval_connect(struct check *check, struct tcpchec
 
        /* Maybe there were an older connection we were waiting on */
        check->wait_list.events = 0;
-       if (s) {
-               _HA_ATOMIC_ADD(&s->curr_used_conns, 1);
-       }
 
        /* no client address */
        if (!sockaddr_alloc(&conn->dst)) {