How to compare 'bereq.backend' and 'req.backend_hint' against a director/backend in Varnish 4.1
Dridi Boukelmoune
dridi at varni.sh
Thu Dec 15 10:26:12 CET 2016
On Thu, Dec 15, 2016 at 9:10 AM, Plöger, Ronald <ronald.ploeger at gmx.de> wrote:
> We are in upgrading from Varnish 3 to Varnish 4.1 and we have experienced a
> problem when comparing 'bereq.backend' or 'req.backend_hint' to a director
> or a backend.
Hi Ronald,
Nice to see some varnishtest usage! The main problem with your code is
that you are confusing directors with VMOD objects. Because the whole
thing is confusing, and we really need to come with good docs because
I can't keep on explaining it. We have bad docs [1] on the topic if you
are interested in the details, but since Varnish 4.0 the things that were
confusing in the code base have become visible to end-users...
> fails with this message:
>
> **** v1 0.4 CLI RX| Message from VCC-compiler:\n
> **** v1 0.4 CLI RX| Backend not found: 'd1'\n
> **** v1 0.4 CLI RX| ('<vcl.inline>' Line 21 Pos 27)\n
> **** v1 0.4 CLI RX| if ( bereq.backend == d1 ) {\n
> **** v1 0.4 CLI RX| --------------------------##----\n
The type system:
- b1 is a backend
- d1 is an object, not a backend
- d1.backend() is a director (and also a backend)
- req.backend_hint takes a director (or a backend)
- bereq.backend takes a backend (or a director)
Why did I distinguish between the last two? Because of how backend
resolution [1] works by default.
What you can do instead is this:
if ( bereq.backend == d1.backend() ) {
...
}
It will work depending on the semantics of the VMOD object. For
objects defined in VMOD directors, it should work with all of them
except the hash director. It appears to fail in Varnish 4.1.3 on my
system. Please check with the latest 4.1 and open a bug if that's
still the case. It works on the master branch, I haven't tried the 5.0
release.
> The question is how to compare 'bereq.backend' and 'req.backend_hint'
> properly against a director/backend.
> Are we missing something or is this a bug?
See above, probably a bit of both!
Also please note that you can avoid the comparisons altogether if it's
only about keeping track of backend selection. You should have seen in
your logs that req.backend_hint would give you the director "d1" and
bereq.backend would give you the selected backend "b1".
This test cases passes on both 4.1.3 and master:
varnishtest "Test backends and directors"
server s1 {
rxreq
txresp
} -start
server s2 {
rxreq
txresp
} -start
varnish v1 -vcl+backend {
import directors;
sub vcl_init {
new d1 = directors.round_robin();
d1.add_backend(s1);
d1.add_backend(s2);
}
sub vcl_recv {
set req.backend_hint = d1.backend();
}
sub vcl_backend_response {
set beresp.http.X-Backend-Response = beresp.backend;
}
sub vcl_deliver {
set resp.http.X-Backend-Deliver = req.backend_hint;
}
} -start
client c1 {
txreq -url "/foo"
rxresp
expect resp.status == 200
expect resp.http.X-Backend-Response == "s1"
expect resp.http.X-Backend-Deliver == "d1"
txreq -url "/bar"
rxresp
expect resp.status == 200
expect resp.http.X-Backend-Response == "s2"
expect resp.http.X-Backend-Deliver == "d1"
} -run
Cheers,
Dridi
Head of the Backends&Directors department
[1] https://www.varnish-cache.org/docs/4.1/reference/directors.html
More information about the varnish-misc
mailing list