MEDIUM: servers: Add a way to keep idle connections alive.
Add a new keyword for servers, "idle-timeout". If set, unused connections are
kept alive until the timeout happens, and will be picked for reuse if no
other connection is available.
diff --git a/src/backend.c b/src/backend.c
index 404c5b3..e62a3b8 100644
--- a/src/backend.c
+++ b/src/backend.c
@@ -1118,6 +1118,7 @@
struct conn_stream *srv_cs = NULL;
struct server *srv;
int reuse = 0;
+ int reuse_orphan = 0;
int err;
int i;
@@ -1189,6 +1190,13 @@
else if (srv->idle_conns && !LIST_ISEMPTY(&srv->idle_conns[tid]) &&
(s->be->options & PR_O_REUSE_MASK) == PR_O_REUSE_ALWS) {
srv_conn = LIST_ELEM(srv->idle_conns[tid].n, struct connection *, list);
+ } else if (srv->idle_orphan_conns && !LIST_ISEMPTY(&srv->idle_orphan_conns[tid]) &&
+ (((s->be->options & PR_O_REUSE_MASK) == PR_O_REUSE_ALWS) ||
+ (((s->be->options & PR_O_REUSE_MASK) != PR_O_REUSE_NEVR) &&
+ s->txn && (s->txn->flags & TX_NOT_FIRST)))) {
+ srv_conn = LIST_ELEM(srv->idle_orphan_conns[tid].n,
+ struct connection *, list);
+ reuse_orphan = 1;
}
/* If we've picked a connection from the pool, we now have to
@@ -1216,6 +1224,15 @@
reuse = 0;
}
}
+ /* If we're really reusing the connection, remove it from the orphan
+ * list and add it back to the idle list.
+ */
+ if (reuse && reuse_orphan) {
+ LIST_DEL(&srv_conn->list);
+ LIST_ADDQ(&srv->idle_conns[tid], &srv_conn->list);
+ if (LIST_ISEMPTY(&srv->idle_orphan_conns[tid]))
+ task_unlink_wq(srv->idle_task[tid]);
+ }
/* We're about to use another connection, let the mux know we're
* done with this one