mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-06 15:17:01 +02:00
MINOR: channel: Use dedicated functions to deal with STREAMER flags
For now, CF_STREAMER and CF_STREAMER_FAST flags are set in sc_conn_recv() function. The logic is moved in dedicated functions. First, channel_check_idletimer() function is now responsible to check the channel's last read date against the idle timer value to be sure the producer is still streaming data. Otherwise, it removes STREAMER flags. Then, channel_check_xfer() function is responsible to check amount of data transferred avec a receive, to eventually update STREAMER flags. In sc_conn_recv(), we now use these functions.
This commit is contained in:
parent
eb67d63456
commit
a40321eb3b
@ -818,6 +818,69 @@ static inline size_t channel_empty(const struct channel *chn)
|
||||
return (IS_HTX_STRM(chn) ? htx_is_empty(htxbuf(&chn->buf)) : c_empty(chn));
|
||||
}
|
||||
|
||||
/* Check channel's last_read date against the idle timeer to verify the producer
|
||||
* is still streaming data or not
|
||||
*/
|
||||
static inline void channel_check_idletimer(struct channel *chn)
|
||||
{
|
||||
if ((chn->flags & (CF_STREAMER | CF_STREAMER_FAST)) && !co_data(chn) &&
|
||||
global.tune.idle_timer &&
|
||||
(unsigned short)(now_ms - chn->last_read) >= global.tune.idle_timer) {
|
||||
/* The buffer was empty and nothing was transferred for more
|
||||
* than one second. This was caused by a pause and not by
|
||||
* congestion. Reset any streaming mode to reduce latency.
|
||||
*/
|
||||
chn->xfer_small = 0;
|
||||
chn->xfer_large = 0;
|
||||
chn->flags &= ~(CF_STREAMER | CF_STREAMER_FAST);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check amount of transferred data after a receive. If <xferred> is greater
|
||||
* than 0, the <last_read> date is updated and STREAMER flags for the channels
|
||||
* are verified.
|
||||
*/
|
||||
static inline void channel_check_xfer(struct channel *chn, size_t xferred)
|
||||
{
|
||||
if (!xferred)
|
||||
return;
|
||||
|
||||
if ((chn->flags & (CF_STREAMER | CF_STREAMER_FAST)) &&
|
||||
(xferred <= c_size(chn) / 2)) {
|
||||
chn->xfer_large = 0;
|
||||
chn->xfer_small++;
|
||||
if (chn->xfer_small >= 3) {
|
||||
/* we have read less than half of the buffer in
|
||||
* one pass, and this happened at least 3 times.
|
||||
* This is definitely not a streamer.
|
||||
*/
|
||||
chn->flags &= ~(CF_STREAMER | CF_STREAMER_FAST);
|
||||
}
|
||||
else if (chn->xfer_small >= 2) {
|
||||
/* if the buffer has been at least half full twchne,
|
||||
* we receive faster than we send, so at least it
|
||||
* is not a "fast streamer".
|
||||
*/
|
||||
chn->flags &= ~CF_STREAMER_FAST;
|
||||
}
|
||||
}
|
||||
else if (!(chn->flags & CF_STREAMER_FAST) && (xferred >= channel_data_limit(chn))) {
|
||||
/* we read a full buffer at once */
|
||||
chn->xfer_small = 0;
|
||||
chn->xfer_large++;
|
||||
if (chn->xfer_large >= 3) {
|
||||
/* we call this buffer a fast streamer if it manages
|
||||
* to be filled in one call 3 consecutive times.
|
||||
*/
|
||||
chn->flags |= (CF_STREAMER | CF_STREAMER_FAST);
|
||||
}
|
||||
}
|
||||
else {
|
||||
chn->xfer_small = 0;
|
||||
chn->xfer_large = 0;
|
||||
}
|
||||
chn->last_read = now_ms;
|
||||
}
|
||||
|
||||
/* Returns the amount of bytes that can be written over the input data at once,
|
||||
* including reserved space which may be overwritten. This is used by Lua to
|
||||
|
48
src/stconn.c
48
src/stconn.c
@ -1251,17 +1251,7 @@ int sc_conn_recv(struct stconn *sc)
|
||||
/* prepare to detect if the mux needs more room */
|
||||
sc_ep_clr(sc, SE_FL_WANT_ROOM);
|
||||
|
||||
if ((ic->flags & (CF_STREAMER | CF_STREAMER_FAST)) && !co_data(ic) &&
|
||||
global.tune.idle_timer &&
|
||||
(unsigned short)(now_ms - ic->last_read) >= global.tune.idle_timer) {
|
||||
/* The buffer was empty and nothing was transferred for more
|
||||
* than one second. This was caused by a pause and not by
|
||||
* congestion. Reset any streaming mode to reduce latency.
|
||||
*/
|
||||
ic->xfer_small = 0;
|
||||
ic->xfer_large = 0;
|
||||
ic->flags &= ~(CF_STREAMER | CF_STREAMER_FAST);
|
||||
}
|
||||
channel_check_idletimer(ic);
|
||||
|
||||
#if defined(USE_LINUX_SPLICE)
|
||||
/* Detect if the splicing is possible depending on the stream policy */
|
||||
@ -1447,41 +1437,7 @@ int sc_conn_recv(struct stconn *sc)
|
||||
if (!cur_read)
|
||||
se_have_no_more_data(sc->sedesc);
|
||||
else {
|
||||
if ((ic->flags & (CF_STREAMER | CF_STREAMER_FAST)) &&
|
||||
(cur_read <= ic->buf.size / 2)) {
|
||||
ic->xfer_large = 0;
|
||||
ic->xfer_small++;
|
||||
if (ic->xfer_small >= 3) {
|
||||
/* we have read less than half of the buffer in
|
||||
* one pass, and this happened at least 3 times.
|
||||
* This is definitely not a streamer.
|
||||
*/
|
||||
ic->flags &= ~(CF_STREAMER | CF_STREAMER_FAST);
|
||||
}
|
||||
else if (ic->xfer_small >= 2) {
|
||||
/* if the buffer has been at least half full twice,
|
||||
* we receive faster than we send, so at least it
|
||||
* is not a "fast streamer".
|
||||
*/
|
||||
ic->flags &= ~CF_STREAMER_FAST;
|
||||
}
|
||||
}
|
||||
else if (!(ic->flags & CF_STREAMER_FAST) && (cur_read >= channel_data_limit(ic))) {
|
||||
/* we read a full buffer at once */
|
||||
ic->xfer_small = 0;
|
||||
ic->xfer_large++;
|
||||
if (ic->xfer_large >= 3) {
|
||||
/* we call this buffer a fast streamer if it manages
|
||||
* to be filled in one call 3 consecutive times.
|
||||
*/
|
||||
ic->flags |= (CF_STREAMER | CF_STREAMER_FAST);
|
||||
}
|
||||
}
|
||||
else {
|
||||
ic->xfer_small = 0;
|
||||
ic->xfer_large = 0;
|
||||
}
|
||||
ic->last_read = now_ms;
|
||||
channel_check_xfer(ic, cur_read);
|
||||
sc_ep_report_read_activity(sc);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user