mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2026-01-31 06:51:11 +01:00
MAJOR: backend: improve the connection reuse mechanism
Now instead of closing the existing connection attached to the stream interface, we first check if the one we pick was attached to another stream interface, in which case the connections are swapped if possible (eg: if the current connection is not private). That way the previous connection remains attached to an existing session and significantly increases the chances of being reused.
This commit is contained in:
parent
8dff998b91
commit
efb90f9dd3
@ -1025,6 +1025,7 @@ int connect_server(struct stream *s)
|
||||
{
|
||||
struct connection *cli_conn;
|
||||
struct connection *srv_conn;
|
||||
struct connection *old_conn;
|
||||
struct server *srv;
|
||||
int reuse = 0;
|
||||
int err;
|
||||
@ -1035,30 +1036,44 @@ int connect_server(struct stream *s)
|
||||
reuse = s->target == srv_conn->target;
|
||||
|
||||
if (srv && !reuse) {
|
||||
if (srv_conn) {
|
||||
srv_conn->owner = NULL;
|
||||
si_release_endpoint(&s->si[1]);
|
||||
old_conn = srv_conn;
|
||||
if (old_conn) {
|
||||
srv_conn = NULL;
|
||||
old_conn->owner = NULL;
|
||||
si_detach_endpoint(&s->si[1]);
|
||||
/* note: if the connection was in a server's idle
|
||||
* queue, it doesn't get dequeued.
|
||||
*/
|
||||
}
|
||||
|
||||
if ((s->be->options & PR_O_REUSE_MASK) == PR_O_REUSE_ALWS &&
|
||||
!LIST_ISEMPTY(&srv->idle_conns)) {
|
||||
/* We're going to have to pick the first connection
|
||||
* from this pool and use it for our purposes. We may
|
||||
* have to get rid of the current idle connection. It
|
||||
* may move to another pool, but we know we're not
|
||||
* interested in it.
|
||||
* have to get rid of the current idle connection, so
|
||||
* for this we try to swap it with the other owner's.
|
||||
* That way it may remain alive for others to pick.
|
||||
*/
|
||||
/* pick first connection. We know there's at least one */
|
||||
srv_conn = LIST_ELEM(srv->idle_conns.n, struct connection *, list);
|
||||
|
||||
LIST_DEL(&srv_conn->list);
|
||||
LIST_INIT(&srv_conn->list);
|
||||
|
||||
si_detach_endpoint(srv_conn->owner);
|
||||
if (srv_conn->owner) {
|
||||
si_detach_endpoint(srv_conn->owner);
|
||||
if (old_conn && !(old_conn->flags & CO_FL_PRIVATE))
|
||||
si_attach_conn(srv_conn->owner, old_conn);
|
||||
}
|
||||
si_attach_conn(&s->si[1], srv_conn);
|
||||
reuse = 1;
|
||||
}
|
||||
|
||||
if (old_conn && !old_conn->owner) {
|
||||
/* we couldn't swap our connection, let's release it */
|
||||
LIST_DEL(&old_conn->list);
|
||||
conn_force_close(old_conn);
|
||||
conn_free(old_conn);
|
||||
}
|
||||
}
|
||||
|
||||
if (reuse) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user