[master] fa38843 Limit backend connection retries to a single retry

Dag Haavi Finstad daghf at varnish-software.com
Mon Nov 20 10:24:10 UTC 2017


commit fa3884391f85565cb7d564cfa5f22d066948d7bc
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 d0fa5bb..c5f9127 100644
--- a/bin/varnishd/cache/cache_backend.c
+++ b/bin/varnishd/cache/cache_backend.c
@@ -74,7 +74,8 @@ static struct lock backends_mtx;
  */
 
 static struct vtp *
-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 vtp *vtp;
 	double tmod;
@@ -112,7 +113,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);
-	vtp = VTP_Get(bp->tcp_pool, tmod, wrk, 0);
+	vtp = VTP_Get(bp->tcp_pool, tmod, wrk, force_fresh);
 	if (vtp == NULL) {
 		VSLb(bo->vsl, SLT_FetchError,
 		     "backend %s: fail", bp->director->display_name);
@@ -221,7 +222,7 @@ vbe_dir_gethdrs(const struct director *d, struct worker *wrk,
 		http_PrintfHeader(bo->bereq, "Host: %s", bp->hosthdr);
 
 	do {
-		vtp = vbe_dir_getfd(wrk, bp, bo);
+		vtp = vbe_dir_getfd(wrk, bp, bo, extrachance == 0);
 		if (vtp == NULL)
 			return (-1);
 		AN(bo->htc);
@@ -256,7 +257,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);
 }
 
@@ -299,7 +300,7 @@ vbe_dir_http1pipe(const struct director *d, struct req *req, struct busyobj *bo)
 
 	req->res_mode = RES_PIPE;
 
-	vtp = vbe_dir_getfd(req->wrk, bp, bo);
+	vtp = vbe_dir_getfd(req->wrk, bp, bo, 0);
 
 	if (vtp == NULL) {
 		retval = SC_TX_ERROR;
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