BUG/MINOR: stream: Attach the read side on the response as soon as possible

A backend stream-interface attached to a reused connection remains in the state
SI_ST_CONN until some data are sent to validate the connection. But when the
url_param algorithm is used to balance connections, no data are sent while the
connection is not established. So it is a chicken and egg situation.

To solve the problem, if no error is detected and when the request channel is
waiting for the connect(), we mark the read side as attached on the response
channel as soon as possible and we wake the request channel up once. This
happens in 2 places. The first one is right after the connect(), when the
stream-interface is still in state SI_ST_CON, in the function
sess_update_st_con_tcp(). The second one is when an applet is used instead of a
real connection to a server, in the function sess_prepare_conn_req(). In fact,
it is done when the backend stream-interface is set to the state SI_ST_EST.

This patch must be backported to 1.9.
This commit is contained in:
Christopher Faulet 2019-05-09 11:46:52 +02:00
parent f4436e145b
commit 7a3367cca0

View File

@ -711,6 +711,16 @@ static int sess_update_st_con_tcp(struct stream *s)
return 1;
}
/* If the request channel is waiting for the connect(), we mark the read
* side as attached on the response channel and we wake up it once. So
* it will have a chance to forward data now.
*/
if (req->flags & CF_WAKE_CONNECT) {
rep->flags |= CF_READ_ATTACHED;
req->flags |= CF_WAKE_ONCE;
req->flags &= ~CF_WAKE_CONNECT;
}
/* we need to wait a bit more if there was no activity either */
if (!(req->flags & CF_WRITE_ACTIVITY))
return 1;
@ -900,10 +910,6 @@ static void sess_establish(struct stream *s)
si_rx_endp_more(si);
rep->flags |= CF_READ_ATTACHED; /* producer is now attached */
if (req->flags & CF_WAKE_CONNECT) {
req->flags |= CF_WAKE_ONCE;
req->flags &= ~CF_WAKE_CONNECT;
}
if (objt_cs(si->end)) {
/* real connections have timeouts */
req->wto = s->be->timeout.server;
@ -1181,6 +1187,17 @@ static void sess_prepare_conn_req(struct stream *s)
return;
}
/* For applets, there is no connection establishment, but if the
* request channel is waiting for it, we mark the read side as
* attached on the response channel and we wake up it once. So
* it will have a chance to forward data now.
*/
if (s->req.flags & CF_WAKE_CONNECT) {
s->res.flags |= CF_READ_ATTACHED;
s->req.flags |= CF_WAKE_ONCE;
s->req.flags &= ~CF_WAKE_CONNECT;
}
if (tv_iszero(&s->logs.tv_request))
s->logs.tv_request = now;
s->logs.t_queue = tv_ms_elapsed(&s->logs.tv_accept, &now);