]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: server: Be smarter about deciding to reuse the last server.
authorOlivier Houchard <cognet@ci0.org>
Sat, 1 Dec 2018 13:40:40 +0000 (14:40 +0100)
committerWilly Tarreau <w@1wt.eu>
Sat, 1 Dec 2018 14:45:30 +0000 (15:45 +0100)
Instead of parsing all the available connections owned by the session
each time we choose a server, even if prefer-last-server is not set,
just do it if prefer-last-server is used, and check if the server is usable,
before checking the connections.

src/backend.c

index cde3c2f40c8c30fdc4a11f7890a27f483751671d..150ea7cde185d62662f8f8cfdcb6368060822294 100644 (file)
@@ -558,7 +558,7 @@ static struct server *get_server_rnd(struct stream *s)
 
 int assign_server(struct stream *s)
 {
-       struct connection *conn;
+       struct connection *conn = NULL;
        struct server *conn_slot;
        struct server *srv = NULL, *prev_srv;
        int err;
@@ -587,22 +587,26 @@ int assign_server(struct stream *s)
        srv = NULL;
        s->target = NULL;
 
-       for (i = 0; i < MAX_SRV_LIST; i++) {
-               list_for_each_entry(conn, &s->sess->srv_list[i].list, session_list) {
-                       if (conn->flags & CO_FL_CONNECTED &&
-                           objt_server(conn->target) &&
-                           __objt_server(conn->target)->proxy == s->be &&
-                           (s->be->lbprm.algo & BE_LB_KIND) != BE_LB_KIND_HI &&
-                           ((s->txn && s->txn->flags & TX_PREFER_LAST) ||
-                            ((s->be->options & PR_O_PREF_LAST) &&
-                             (!s->be->max_ka_queue ||
-                              server_has_room(__objt_server(conn->target)) ||
-                              (__objt_server(conn->target)->nbpend + 1) < s->be->max_ka_queue))) &&
-                           srv_currently_usable(__objt_server(conn->target))) {
-                               srv = __objt_server(conn->target);
-                               s->target = &srv->obj_type;
-                               goto out_ok;
+       if ((s->be->lbprm.algo & BE_LB_KIND) != BE_LB_KIND_HI &&
+           ((s->txn && s->txn->flags & TX_PREFER_LAST) ||
+            (s->be->options & PR_O_PREF_LAST))) {
+               for (i = 0; i < MAX_SRV_LIST; i++) {
+                       struct server *tmpsrv = objt_server(s->sess->srv_list[i].target);
 
+                       if (tmpsrv && tmpsrv->proxy == s->be &&
+                           ((s->txn && s->txn->flags & TX_PREFER_LAST) ||
+                            (!s->be->max_ka_queue ||
+                             server_has_room(tmpsrv) || (
+                             tmpsrv->nbpend + 1 < s->be->max_ka_queue))) &&
+                           srv_currently_usable(tmpsrv)) {
+                               list_for_each_entry(conn, &s->sess->srv_list[i].list, session_list) {
+                                       if (conn->flags & CO_FL_CONNECTED) {
+
+                                               srv = tmpsrv;
+                                               s->target = &srv->obj_type;
+                                               goto out_ok;
+                                       }
+                               }
                        }
                }
        }