[4.1] a8da6ea Limit backend connection retries to a single retry

Dag Haavi Finstad daghf at varnish-software.com
Mon Nov 27 16:36:10 UTC 2017


commit a8da6ead25479f20acfc23f85e90c1629bfba486
Author: Dag Haavi Finstad <daghf at varnish-software.com>
Date:   Thu Nov 16 13:09:34 2017 +0100

    Limit backend connection retries to a single retry
    
    The second time around, we force a fresh connection.
    
    The VCL user may choose to do 'return (retry);' in vcl_backend_error{}
    if further attempts are deemed warranted.
    
    Fixes: #2135

diff --git a/bin/varnishd/cache/cache_backend.c b/bin/varnishd/cache/cache_backend.c
index 4133359..bc5a244 100644
--- a/bin/varnishd/cache/cache_backend.c
+++ b/bin/varnishd/cache/cache_backend.c
@@ -59,7 +59,8 @@
  */
 
 static struct vbc *
-vbe_dir_getfd(struct worker *wrk, struct backend *bp, struct busyobj *bo)
+vbe_dir_getfd(struct worker *wrk, struct backend *bp, struct busyobj *bo,
+    unsigned force_fresh)
 {
 	struct vbc *vc;
 	double tmod;
@@ -91,7 +92,7 @@ vbe_dir_getfd(struct worker *wrk, struct backend *bp, struct busyobj *bo)
 	bo->htc->doclose = SC_NULL;
 
 	FIND_TMO(connect_timeout, tmod, bo, bp);
-	vc = VBT_Get(bp->tcp_pool, tmod, bp, wrk, 0);
+	vc = VBT_Get(bp->tcp_pool, tmod, bp, wrk, force_fresh);
 	if (vc == NULL) {
 		// XXX: Per backend stats ?
 		VSC_C_main->backend_fail++;
@@ -196,7 +197,7 @@ vbe_dir_gethdrs(const struct director *d, struct worker *wrk,
 		http_PrintfHeader(bo->bereq, "Host: %s", bp->hosthdr);
 
 	do {
-		vbc = vbe_dir_getfd(wrk, bp, bo);
+		vbc = vbe_dir_getfd(wrk, bp, bo, extrachance == 0);
 		if (vbc == NULL) {
 			VSLb(bo->vsl, SLT_FetchError, "no backend connection");
 			return (-1);
@@ -233,7 +234,7 @@ vbe_dir_gethdrs(const struct director *d, struct worker *wrk,
 		    bo->req->req_body_status != REQ_BODY_CACHED)
 			break;
 		VSC_C_main->backend_retry++;
-	} while (extrachance);
+	} while (extrachance--);
 	return (-1);
 }
 
@@ -289,7 +290,7 @@ vbe_dir_http1pipe(const struct director *d, struct req *req, struct busyobj *bo)
 
 	req->res_mode = RES_PIPE;
 
-	vbc = vbe_dir_getfd(req->wrk, bp, bo);
+	vbc = vbe_dir_getfd(req->wrk, bp, bo, 0);
 
 	if (vbc == NULL) {
 		VSLb(bo->vsl, SLT_FetchError, "no backend connection");
diff --git a/bin/varnishtest/tests/r02135.vtc b/bin/varnishtest/tests/r02135.vtc
new file mode 100644
index 0000000..3868bd3
--- /dev/null
+++ b/bin/varnishtest/tests/r02135.vtc
@@ -0,0 +1,40 @@
+varnishtest "#2135: fetch retry logic"
+
+barrier b1 cond 2
+
+server s1 {
+	rxreq
+	txresp
+	rxreq
+	expect req.url == "/foo"
+	delay 2.5
+	send " "
+	expect_close
+	accept
+	rxreq
+	expect req.url == "/foo"
+	barrier b1 sync
+	delay 2.5
+	send " "
+	expect_close
+} -start
+
+varnish v1 -cliok "param.set between_bytes_timeout 1"
+varnish v1 -cliok "param.set first_byte_timeout 1"
+
+varnish v1 -vcl+backend {
+	sub vcl_backend_error {
+		set beresp.http.url = bereq.url;
+	}
+} -start
+
+client c1 {
+	txreq
+	rxresp
+	expect resp.status == "200"
+	txreq -url "/foo"
+	barrier b1 sync
+	rxresp
+	expect resp.status == "503"
+	expect resp.http.url == "/foo"
+} -run


More information about the varnish-commit mailing list