MEDIUM: server: Be smarter about deciding to reuse the last server.

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.
This commit is contained in:
Olivier Houchard 2018-12-01 14:40:40 +01:00 committed by Willy Tarreau
parent 985f139aa2
commit ba4fff5fd2

View File

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