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