mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2024-12-16 00:14:31 +00:00
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:
parent
f4436e145b
commit
7a3367cca0
25
src/stream.c
25
src/stream.c
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user