Commit de2fd54b authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Add an optional shortcut:

The parameter session_linger determines how many milliseconds the
workerthread waits to see if another request has arrived, before
handing the session over to the session herder.

If we manage to catch the next request this way, we save a number
of semi-expensive steps, if we hang around too long, the worker-thread
gets to goof off.

A relatively small sample of data from a live server, indicates
that 20% of all requests arrive within 50 msec of the previous
request and 50% within 100msec.

It is not clear at present how these timeintervals relate to client
RTT, or if they are systematically too high, due to the duration
of the detour over the herder.

There is a new line in varnishstat keeping track of how many times
this gamble succeeds.

Experimentation is encouraged.




git-svn-id: http://www.varnish-cache.org/svn/trunk/varnish-cache@2663 d4fa192b-c00b-0410-8231-f00ffab90ce4
parent 994cde5a
...@@ -61,6 +61,7 @@ DOT acceptor -> start [style=bold,color=green,weight=4] ...@@ -61,6 +61,7 @@ DOT acceptor -> start [style=bold,color=green,weight=4]
#include <stdio.h> #include <stdio.h>
#include <errno.h> #include <errno.h>
#include <math.h> #include <math.h>
#include <poll.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
...@@ -198,6 +199,7 @@ static int ...@@ -198,6 +199,7 @@ static int
cnt_done(struct sess *sp) cnt_done(struct sess *sp)
{ {
double dh, dp, da; double dh, dp, da;
struct pollfd pfd[1];
int i; int i;
CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
...@@ -267,6 +269,17 @@ cnt_done(struct sess *sp) ...@@ -267,6 +269,17 @@ cnt_done(struct sess *sp)
sp->step = STP_AGAIN; sp->step = STP_AGAIN;
return (0); return (0);
} }
if (params->session_linger > 0) {
pfd[0].fd = sp->fd;
pfd[0].events = POLLIN;
pfd[0].revents = 0;
i = poll(pfd, 1, params->session_linger);
if (i > 0) {
VSL_stats->sess_linger++;
sp->step = STP_AGAIN;
return (0);
}
}
VSL_stats->sess_herd++; VSL_stats->sess_herd++;
SES_Charge(sp); SES_Charge(sp);
assert(!isnan(sp->wrk->used)); assert(!isnan(sp->wrk->used));
......
...@@ -148,6 +148,9 @@ struct params { ...@@ -148,6 +148,9 @@ struct params {
/* Default connection_timeout */ /* Default connection_timeout */
unsigned connect_timeout; unsigned connect_timeout;
/* How long to linger on sessions */
unsigned session_linger;
/* CLI buffer size */ /* CLI buffer size */
unsigned cli_buffer; unsigned cli_buffer;
......
...@@ -718,6 +718,18 @@ static const struct parspec parspec[] = { ...@@ -718,6 +718,18 @@ static const struct parspec parspec[] = {
"VCL can override this default value for each backend.", "VCL can override this default value for each backend.",
0, 0,
"400", "ms" }, "400", "ms" },
{ "session_linger", tweak_uint,
&master.session_linger,0, UINT_MAX,
"How long time the workerthread lingers on the session "
"to see if a new request appears right away.\n"
"If sessions are reused, as much as half of all reuses "
"happen within the first 100 msec of the previous request "
"completing.\n"
"Setting this too high results in worker threads not doing "
"anything for their keep, setting it too low just means that "
"more sessions take a detour around the acceptor.",
EXPERIMENTAL,
"0", "ms" },
{ "cli_buffer", tweak_uint, &master.cli_buffer, 4096, UINT_MAX, { "cli_buffer", tweak_uint, &master.cli_buffer, 4096, UINT_MAX,
"Size of buffer for CLI input." "Size of buffer for CLI input."
"\nYou may need to increase this if you have big VCL files " "\nYou may need to increase this if you have big VCL files "
......
...@@ -85,6 +85,7 @@ MAC_STAT(s_bodybytes, uint64_t, 'a', "Total body bytes") ...@@ -85,6 +85,7 @@ MAC_STAT(s_bodybytes, uint64_t, 'a', "Total body bytes")
MAC_STAT(sess_closed, uint64_t, 'a', "Session Closed") MAC_STAT(sess_closed, uint64_t, 'a', "Session Closed")
MAC_STAT(sess_pipeline, uint64_t, 'a', "Session Pipeline") MAC_STAT(sess_pipeline, uint64_t, 'a', "Session Pipeline")
MAC_STAT(sess_readahead, uint64_t, 'a', "Session Read Ahead") MAC_STAT(sess_readahead, uint64_t, 'a', "Session Read Ahead")
MAC_STAT(sess_linger, uint64_t, 'a', "Session Linger")
MAC_STAT(sess_herd, uint64_t, 'a', "Session herd") MAC_STAT(sess_herd, uint64_t, 'a', "Session herd")
MAC_STAT(shm_records, uint64_t, 'a', "SHM records") MAC_STAT(shm_records, uint64_t, 'a', "SHM records")
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment