[master] 51e0af5 Allow grace-hits on hit-for-pass objects, and treat the first one (which gets the busyobj) as a miss.

Poul-Henning Kamp phk at FreeBSD.org
Mon Nov 23 23:27:48 CET 2015


commit 51e0af5ad29b9f1c15958c05b67dccfcb2beb95b
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Mon Nov 23 22:17:53 2015 +0000

    Allow grace-hits on hit-for-pass objects, and treat the first one
    (which gets the busyobj) as a miss.
    
    Testcase by:	daghf
    Fixes:	1818

diff --git a/bin/varnishd/cache/cache_hash.c b/bin/varnishd/cache/cache_hash.c
index 3580204..f841c53 100644
--- a/bin/varnishd/cache/cache_hash.c
+++ b/bin/varnishd/cache/cache_hash.c
@@ -441,8 +441,7 @@ HSH_Lookup(struct req *req, struct objcore **ocp, struct objcore **bocp,
 			*ocp = oc;
 			return (HSH_HIT);
 		}
-		if (oc->exp.t_origin > exp_t_origin &&
-		    !(oc->flags & OC_F_PASS)) {
+		if (oc->exp.t_origin > exp_t_origin) {
 			/* record the newest object */
 			exp_oc = oc;
 			exp_t_origin = oc->exp.t_origin;
diff --git a/bin/varnishd/cache/cache_req_fsm.c b/bin/varnishd/cache/cache_req_fsm.c
index da59078..f30ab59 100644
--- a/bin/varnishd/cache/cache_req_fsm.c
+++ b/bin/varnishd/cache/cache_req_fsm.c
@@ -403,16 +403,22 @@ cnt_lookup(struct worker *wrk, struct req *req)
 	AZ(oc->flags & OC_F_BUSY);
 	req->objcore = oc;
 
-	if (oc->flags & OC_F_PASS) {
+	if ((oc->flags & OC_F_PASS) && boc != NULL) {
+		/* Treat a graced Hit-For-Pass as a miss */
+		req->objcore = boc;
+		req->stale_oc = oc;
+		req->req_step = R_STP_MISS;
+		return (REQ_FSM_MORE);
+	} else if (oc->flags & OC_F_PASS) {
 		/* Found a hit-for-pass */
 		VSLb(req->vsl, SLT_Debug, "XXXX HIT-FOR-PASS");
 		VSLb(req->vsl, SLT_HitPass, "%u",
 		    ObjGetXID(wrk, req->objcore));
-		AZ(boc);
 		(void)HSH_DerefObjCore(wrk, &req->objcore);
 		wrk->stats->cache_hitpass++;
 		req->req_step = R_STP_PASS;
 		return (REQ_FSM_MORE);
+	} else if (oc->flags & OC_F_PASS) {
 	}
 
 	VSLb(req->vsl, SLT_Hit, "%u", ObjGetXID(wrk, req->objcore));
diff --git a/bin/varnishtest/tests/r01818.vtc b/bin/varnishtest/tests/r01818.vtc
new file mode 100644
index 0000000..8b38c9b
--- /dev/null
+++ b/bin/varnishtest/tests/r01818.vtc
@@ -0,0 +1,75 @@
+varnishtest "#1818: verify that grace works for hit_for_pass objects"
+
+server s1 {
+	rxreq
+	expect req.http.a == "1"
+	txresp
+
+	rxreq
+	expect req.http.b == "1"
+	sema r2 sync 2
+	sema r1 sync 2
+ 	txresp
+} -start
+
+server s2 {
+	rxreq
+	expect req.http.c == "1"
+	sema r1 sync 2
+	txresp
+} -start
+
+varnish v1 -vcl+backend {
+	sub vcl_recv {
+		if (req.http.c) {
+			set req.backend_hint = s2;
+		}
+	}
+
+	sub vcl_miss {
+		set req.http.miss = "1";
+	}
+
+	sub vcl_pass {
+		set req.http.pass = "1";
+	}
+
+	sub vcl_deliver {
+		if (req.http.miss) {
+			set resp.http.miss = req.http.miss;
+		}
+		if (req.http.pass) {
+			set resp.http.pass = req.http.pass;
+		}
+	}
+
+	sub vcl_backend_response {
+		set beresp.ttl = 0.1s;
+		set beresp.grace = 1m;
+		set beresp.uncacheable = true;
+	}
+} -start 
+
+varnish v1 -cliok "param.set debug +syncvsl"
+varnish v1 -cliok "param.set debug +waitinglist"
+varnish v1 -cliok "param.show debug"
+
+client c1 {
+	# This is a plain miss
+	txreq -hdr "a: 1"
+	rxresp
+	expect resp.http.miss == "1"
+	delay .2
+
+	# This should also miss, because the HFP is expired
+	txreq -hdr "b: 1"
+	rxresp
+	expect resp.http.miss == "1"
+} -start
+
+client c2 {
+	sema r2 sync 2
+	txreq -hdr "c: 1"
+	rxresp
+	expect resp.http.pass == "1"
+} -run



More information about the varnish-commit mailing list