MEDIUM: stream-int: queue idle connections at the server

Now we get a per-server list of all idle connections. That way we'll
be able to reclaim them upon shortage later.
This commit is contained in:
Willy Tarreau 2015-08-04 19:00:17 +02:00
parent d75d40e9a8
commit 323a2d925c
4 changed files with 23 additions and 3 deletions

View File

@ -25,6 +25,7 @@
#include <stdlib.h>
#include <common/config.h>
#include <types/server.h>
#include <types/stream.h>
#include <types/stream_interface.h>
#include <proto/applet.h>
@ -154,6 +155,7 @@ static inline void si_release_endpoint(struct stream_interface *si)
return;
if ((conn = objt_conn(si->end))) {
LIST_DEL(&conn->list);
conn_force_close(conn);
conn_free(conn);
}
@ -167,15 +169,19 @@ static inline void si_release_endpoint(struct stream_interface *si)
/* Turn a possibly existing connection endpoint of stream interface <si> to
* idle mode, which means that the connection will be polled for incoming events
* and might be killed by the underlying I/O handler.
* and might be killed by the underlying I/O handler. If <pool> is not null, the
* connection will also be added at the head of this list.
*/
static inline void si_idle_conn(struct stream_interface *si)
static inline void si_idle_conn(struct stream_interface *si, struct list *pool)
{
struct connection *conn = objt_conn(si->end);
if (!conn)
return;
if (pool)
LIST_ADD(pool, &conn->list);
conn_attach(conn, si, &si_idle_conn_cb);
conn_data_want_recv(conn);
}

View File

@ -1052,6 +1052,11 @@ int connect_server(struct stream *s)
if (!reuse)
srv_conn = si_alloc_conn(&s->si[1]);
else {
/* reusing our connection, take it out of the idle list */
LIST_DEL(&srv_conn->list);
LIST_INIT(&srv_conn->list);
}
if (!srv_conn)
return SF_ERR_RESOURCE;

View File

@ -5030,12 +5030,15 @@ void http_end_txn_clean_session(struct stream *s)
{
int prev_status = s->txn->status;
struct proxy *fe = strm_fe(s);
struct connection *srv_conn;
struct server *srv;
/* FIXME: We need a more portable way of releasing a backend's and a
* server's connections. We need a safer way to reinitialize buffer
* flags. We also need a more accurate method for computing per-request
* data.
*/
srv_conn = objt_conn(s->si[1].end);
/* unless we're doing keep-alive, we want to quickly close the connection
* to the server.
@ -5125,6 +5128,7 @@ void http_end_txn_clean_session(struct stream *s)
if (((s->txn->flags & TX_CON_WANT_MSK) != TX_CON_WANT_KAL) ||
!si_conn_ready(&s->si[1])) {
si_release_endpoint(&s->si[1]);
srv_conn = NULL;
}
s->si[1].state = s->si[1].prev_state = SI_ST_INI;
@ -5182,7 +5186,11 @@ void http_end_txn_clean_session(struct stream *s)
channel_auto_close(&s->res);
/* we're in keep-alive with an idle connection, monitor it */
si_idle_conn(&s->si[1]);
srv = NULL;
if (srv_conn)
srv = objt_server(srv_conn->target);
si_idle_conn(&s->si[1], srv ? &srv->priv_conns : NULL);
s->req.analysers = strm_li(s)->analysers;
s->res.analysers = 0;

View File

@ -515,6 +515,7 @@ static int si_idle_conn_wake_cb(struct connection *conn)
if (conn->flags & (CO_FL_ERROR | CO_FL_SOCK_RD_SH)) {
/* warning, we can't do anything on <conn> after this call ! */
LIST_DEL(&conn->list);
conn_force_close(conn);
conn_free(conn);
si->end = NULL;