diff --git a/bin/varnishtest/tests/d00021.vtc b/bin/varnishtest/tests/d00021.vtc index 963356188f1..109a4a5fb4c 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 @@ -54,6 +54,10 @@ varnish v1 -vcl+backend { } sub vcl_recv { + # coverage + set req.backend_hint = directors.resolve(vd.backend()); + set req.backend_hint = directors.resolve(l.backend()); + set req.backend_hint = directors.resolve(ll.backend()); return(pass); } @@ -86,7 +90,10 @@ varnish v1 -vcl+backend { } sub vcl_backend_fetch { - if (bereq.http.layered) { + if (bereq.http.resolve) { + call backend_fetch_layered; + set bereq.backend = directors.resolve(bereq.backend); + } else if (bereq.http.layered) { call backend_fetch_layered; } else { call backend_fetch_direct; @@ -148,4 +155,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/lib/libvmod_directors/misc.c b/lib/libvmod_directors/misc.c index d70c8ce556a..bcf29b35063 100644 --- a/lib/libvmod_directors/misc.c +++ b/lib/libvmod_directors/misc.c @@ -33,6 +33,8 @@ #include "vdef.h" #include "vrt.h" #include "vcl.h" +#include "vas.h" +#include "miniobj.h" #include "vcc_if.h" @@ -47,3 +49,11 @@ VPFX(lookup)(VRT_CTX, VCL_STRING name) return (VRT_LookupDirector(ctx, name)); } + +VCL_BACKEND +VPFX(resolve)(VRT_CTX, VCL_BACKEND d) +{ + CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC); + + return (VRT_DirectorResolve(ctx, d)); +} diff --git a/lib/libvmod_directors/vmod.vcc b/lib/libvmod_directors/vmod.vcc index 054b6c34e9f..67825facbc9 100644 --- a/lib/libvmod_directors/vmod.vcc +++ b/lib/libvmod_directors/vmod.vcc @@ -711,6 +711,28 @@ Lookup a backend by its name. This function can only be used from ``vcl_init{}`` and ``vcl_fini{}``. +$Function BACKEND resolve(BACKEND) + +Return a backend which any layer of directors resolves to. + +Most ``.backend()`` methods of varnish directors return a reference to +the director itself (basically, all except ``shard`` with +``resolve=NOW``). Only when it is time to make an actual connection is +the decision on which backend to contact made. + +This function allows to have that decision made early, it returns a +final ("real") backend which the given director argument would +return. + +Notice that this decision is not saved, in other words, repeated calls +to `directors.resolve()`_ may return different values, and the implicit +resolution may use a different value yet again. + +To make a resolution decision permanent, it has to be saved +explicitly, for example by assignment to ``(be)req.backend`` as in:: + + set bereq.backend = directors.resolve(bereq.backend); + ACKNOWLEDGEMENTS ================