[master] 97e8a9f58 Make .resolve() a type specific method of BACKEND

Nils Goroll nils.goroll at uplex.de
Wed May 13 15:38:06 UTC 2020


commit 97e8a9f58ac4270215f2c2529d9d0897f7d9b168
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Mon May 11 08:45:01 2020 +0000

    Make .resolve() a type specific method of BACKEND
    
    This is an alternative implementation of #2680

diff --git a/bin/varnishd/cache/cache_director.c b/bin/varnishd/cache/cache_director.c
index fe5b132b9..aebbc7a71 100644
--- a/bin/varnishd/cache/cache_director.c
+++ b/bin/varnishd/cache/cache_director.c
@@ -80,27 +80,32 @@ VDI_Ahealth(const struct director *d)
 
 /* Resolve director --------------------------------------------------*/
 
+VCL_BACKEND
+VRT_VDI_Resolve(VRT_CTX, VCL_BACKEND d)
+{
+	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
+
+	while (d != NULL) {
+		CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC);
+		AN(d->vdir);
+		if (d->vdir->methods->resolve == NULL)
+			break;
+		d = d->vdir->methods->resolve(ctx, d);
+		CHECK_OBJ_ORNULL(d, DIRECTOR_MAGIC);
+	}
+        return (d);
+}
+
 static VCL_BACKEND
 VDI_Resolve(VRT_CTX)
 {
 	const struct director *d;
-	const struct director *d2;
 	struct busyobj *bo;
 
 	bo = ctx->bo;
 	CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
 	CHECK_OBJ_ORNULL(bo->director_req, DIRECTOR_MAGIC);
-
-	for (d = bo->director_req; d != NULL &&
-	    d->vdir->methods->resolve != NULL; d = d2) {
-		CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC);
-		AN(d->vdir);
-		d2 = d->vdir->methods->resolve(ctx, d);
-		if (d2 == NULL)
-			VSLb(bo->vsl, SLT_FetchError,
-			    "Director %s returned no backend", d->vcl_name);
-	}
-
+	d = VRT_VDI_Resolve(ctx, bo->director_req);
 	CHECK_OBJ_ORNULL(d, DIRECTOR_MAGIC);
 	if (d == NULL) {
 		VSLb(bo->vsl, SLT_FetchError, "No backend");
diff --git a/bin/varnishtest/tests/d00021.vtc b/bin/varnishtest/tests/d00021.vtc
index 963356188..91930c18b 100644
--- a/bin/varnishtest/tests/d00021.vtc
+++ b/bin/varnishtest/tests/d00021.vtc
@@ -1,16 +1,16 @@
 varnishtest "shard director LAZY and layering"
 
-server s1 -repeat 2 {
+server s1 -repeat 3 {
 	rxreq
 	txresp -body "ech3Ooj"
 } -start
 
-server s2 -repeat 2 {
+server s2 -repeat 3 {
 	rxreq
 	txresp -body "ieQu2qua"
 } -start
 
-server s3 -repeat 2 {
+server s3 -repeat 3 {
 	rxreq
 	txresp -body "xiuFi3Pe"
 } -start
@@ -88,6 +88,9 @@ varnish v1 -vcl+backend {
 	sub vcl_backend_fetch {
 	    if (bereq.http.layered) {
 		call backend_fetch_layered;
+            } else if (bereq.http.resolve) {
+                call backend_fetch_layered;
+                set bereq.backend = bereq.backend.resolve();
 	    } else {
 		call backend_fetch_direct;
 	    }
@@ -148,4 +151,25 @@ client c1 {
 	expect resp.http.healthy == "true"
 	expect resp.http.director == "ll"
 	expect resp.http.backend == "s3"
+
+	txreq -url /1 -hdr "resolve: true"
+	rxresp
+	expect resp.body == "ech3Ooj"
+	expect resp.http.healthy == "true"
+	expect resp.http.director == "s1"
+	expect resp.http.backend == "s1"
+
+	txreq -url /2 -hdr "resolve: true"
+	rxresp
+	expect resp.body == "ieQu2qua"
+	expect resp.http.healthy == "true"
+	expect resp.http.director == "s2"
+	expect resp.http.backend == "s2"
+
+	txreq -url /3 -hdr "resolve: true"
+	rxresp
+	expect resp.body == "xiuFi3Pe"
+	expect resp.http.healthy == "true"
+	expect resp.http.director == "s3"
+	expect resp.http.backend == "s3"
 } -run
diff --git a/include/vrt.h b/include/vrt.h
index 6d5dcdc93..9e8a91191 100644
--- a/include/vrt.h
+++ b/include/vrt.h
@@ -435,6 +435,7 @@ struct vrt_backend_probe {
 	VRT_BACKEND_PROBE_FIELDS(const)
 };
 
+VCL_BACKEND VRT_VDI_Resolve(VRT_CTX, VCL_BACKEND);
 
 /***********************************************************************
  * Implementation details of ACLs
diff --git a/lib/libvcc/vcc_expr.c b/lib/libvcc/vcc_expr.c
index dd62b279d..1b0494e11 100644
--- a/lib/libvcc/vcc_expr.c
+++ b/lib/libvcc/vcc_expr.c
@@ -839,6 +839,7 @@ static const struct vcc_methods {
 
 	{ STRINGS, STRING, "upper", "VRT_UpperLowerStrands(ctx, \vT, 1)", 1 },
 	{ STRINGS, STRING, "lower", "VRT_UpperLowerStrands(ctx, \vT, 0)", 1 },
+	{ BACKEND, BACKEND, "resolve", "VRT_VDI_Resolve(ctx, \v1)", 1 },
 
 	{ NULL, NULL,		NULL,		NULL},
 };


More information about the varnish-commit mailing list