Commit 1369592d authored by Kristian Lyngstol's avatar Kristian Lyngstol Committed by Tollef Fog Heen

Ensure ban lurker sleeps 1.0s on failure

As per documentation, the ban lurker sleeps ban_lurker_sleep when it is
successful, but on failure it should only sleep 1.0s. No point hammering
the ban list every 0.01s if bans aren't even used.

Fixes #1030

Conflicts:

	bin/varnishd/cache_ban.c
parent 0e3fd5b2
...@@ -738,7 +738,7 @@ BAN_CheckObject(struct object *o, const struct sess *sp) ...@@ -738,7 +738,7 @@ BAN_CheckObject(struct object *o, const struct sess *sp)
* Ban tail lurker thread * Ban tail lurker thread
*/ */
static void static int
ban_lurker_work(const struct sess *sp) ban_lurker_work(const struct sess *sp)
{ {
struct ban *b, *bf; struct ban *b, *bf;
...@@ -757,21 +757,21 @@ ban_lurker_work(const struct sess *sp) ...@@ -757,21 +757,21 @@ ban_lurker_work(const struct sess *sp)
if (bf != NULL) { if (bf != NULL) {
Lck_Unlock(&ban_mtx); Lck_Unlock(&ban_mtx);
BAN_Free(bf); BAN_Free(bf);
return; return (0);
} }
/* Find the last ban give up, if we have only one */ /* Find the last ban give up, if we have only one */
b = VTAILQ_LAST(&ban_head, banhead_s); b = VTAILQ_LAST(&ban_head, banhead_s);
if (b == ban_start) { if (b == ban_start) {
Lck_Unlock(&ban_mtx); Lck_Unlock(&ban_mtx);
return; return (0);
} }
/* Find the first object on it, if any */ /* Find the first object on it, if any */
oc = VTAILQ_FIRST(&b->objcore); oc = VTAILQ_FIRST(&b->objcore);
if (oc == NULL) { if (oc == NULL) {
Lck_Unlock(&ban_mtx); Lck_Unlock(&ban_mtx);
return; return (0);
} }
/* Try to lock the objhead */ /* Try to lock the objhead */
...@@ -779,7 +779,7 @@ ban_lurker_work(const struct sess *sp) ...@@ -779,7 +779,7 @@ ban_lurker_work(const struct sess *sp)
CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC); CHECK_OBJ_NOTNULL(oh, OBJHEAD_MAGIC);
if (Lck_Trylock(&oh->mtx)) { if (Lck_Trylock(&oh->mtx)) {
Lck_Unlock(&ban_mtx); Lck_Unlock(&ban_mtx);
return; return (0);
} }
/* /*
...@@ -792,7 +792,7 @@ ban_lurker_work(const struct sess *sp) ...@@ -792,7 +792,7 @@ ban_lurker_work(const struct sess *sp)
if (oc2 == NULL) { if (oc2 == NULL) {
Lck_Unlock(&oh->mtx); Lck_Unlock(&oh->mtx);
Lck_Unlock(&ban_mtx); Lck_Unlock(&ban_mtx);
return; return (0);
} }
/* /*
* Grab a reference to the OC and we can let go of the BAN mutex * Grab a reference to the OC and we can let go of the BAN mutex
...@@ -809,12 +809,13 @@ ban_lurker_work(const struct sess *sp) ...@@ -809,12 +809,13 @@ ban_lurker_work(const struct sess *sp)
Lck_Unlock(&oh->mtx); Lck_Unlock(&oh->mtx);
WSP(sp, SLT_Debug, "lurker: %p %g %d", oc, o->exp.ttl, i); WSP(sp, SLT_Debug, "lurker: %p %g %d", oc, o->exp.ttl, i);
(void)HSH_Deref(sp->wrk, NULL, &o); (void)HSH_Deref(sp->wrk, NULL, &o);
return (i);
} }
static void * __match_proto__(bgthread_t) static void * __match_proto__(bgthread_t)
ban_lurker(struct sess *sp, void *priv) ban_lurker(struct sess *sp, void *priv)
{ {
int i = 0;
(void)priv; (void)priv;
while (1) { while (1) {
if (params->ban_lurker_sleep == 0.0) { if (params->ban_lurker_sleep == 0.0) {
...@@ -822,8 +823,11 @@ ban_lurker(struct sess *sp, void *priv) ...@@ -822,8 +823,11 @@ ban_lurker(struct sess *sp, void *priv)
TIM_sleep(1.0); TIM_sleep(1.0);
continue; continue;
} }
TIM_sleep(params->ban_lurker_sleep); if (i != 0)
ban_lurker_work(sp); TIM_sleep(params->ban_lurker_sleep);
else
TIM_sleep(1.0);
i = ban_lurker_work(sp);
WSL_Flush(sp->wrk, 0); WSL_Flush(sp->wrk, 0);
WRK_SumStat(sp->wrk); WRK_SumStat(sp->wrk);
} }
......
varnishtest "Test ban_lurker_sleep vs failed ban lurker"
# The idea here is that the ban lurker should always wait 1 second when it
# can't proceed, as per documentation and original intent. The
# ban_lurker_sleep should not affect sleep-times when the lurker fails.
server s1 {
rxreq
txresp -status 200
rxreq
txresp -status 200
} -start
varnish v1 -vcl+backend {
sub vcl_recv {
if (req.request == "BAN") {
ban("obj.http.url ~ /");
error 201 "banned";
}
return (lookup);
}
sub vcl_fetch {
set beresp.http.url = req.url;
}
} -start
varnish v1 -cliok "param.set ban_lurker_sleep 0.01"
varnish v1 -expect n_ban_obj_test == 0
delay 0.01
client c1 {
txreq -req GET
rxresp
expect resp.status == 200
txreq -req BAN
rxresp
expect resp.status == 201
} -run
delay 0.1
varnish v1 -expect n_ban_obj_test == 0
delay 1.0
varnish v1 -expect n_ban_obj_test == 1
varnish v1 -cliok "param.set ban_lurker_sleep 5.01"
client c2 {
txreq -req GET
rxresp
expect resp.status == 200
txreq -req BAN
rxresp
expect resp.status == 201
} -run
delay 0.1
varnish v1 -expect n_ban_obj_test == 1
delay 1.1
varnish v1 -expect n_ban_obj_test == 2
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