Commit d85dde64 authored by Martin Blix Grydeland's avatar Martin Blix Grydeland

Make random/hash director exhaust the backend list when looking for

healthy backend.

Fixes: #1575
parent d11d4419
varnishtest "#1575 - random director exhaust backend list"
# Add 5 backends to a random director, with the 5th having very low weight.
# Mark the first 4 sick, and make sure that the 5th will be selected.
server s1 {
rxreq
txresp
} -start
server s2 {
rxreq
txresp
} -start
server s3 {
rxreq
txresp
} -start
server s4 {
rxreq
txresp
} -start
server s5 {
rxreq
txresp
} -start
varnish v1 -vcl+backend {
import ${vmod_directors};
sub vcl_init {
new rd = directors.random();
rd.add_backend(s1, 10000);
rd.add_backend(s2, 10000);
rd.add_backend(s3, 10000);
rd.add_backend(s4, 10000);
rd.add_backend(s5, 1);
}
sub vcl_backend_fetch {
set bereq.backend = rd.backend();
}
} -start
varnish v1 -cliok "backend.set_health s1 sick"
varnish v1 -cliok "backend.set_health s2 sick"
varnish v1 -cliok "backend.set_health s3 sick"
varnish v1 -cliok "backend.set_health s4 sick"
client c1 {
txreq
rxresp
expect resp.status == 200
} -run
......@@ -47,7 +47,7 @@ struct vmod_directors_hash {
unsigned magic;
#define VMOD_DIRECTORS_HASH_MAGIC 0xc08dd611
struct vdir *vd;
unsigned nloops;
unsigned n_backend;
struct vbitmap *vbm;
};
......@@ -64,7 +64,6 @@ vmod_hash__init(const struct vrt_ctx *ctx, struct vmod_directors_hash **rrp,
AN(rr);
rr->vbm = vbit_init(8);
AN(rr->vbm);
rr->nloops = 3; //
*rrp = rr;
vdir_new(&rr->vd, vcl_name, NULL, NULL, rr);
}
......@@ -90,6 +89,7 @@ vmod_hash_add_backend(const struct vrt_ctx *ctx,
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
CHECK_OBJ_NOTNULL(rr, VMOD_DIRECTORS_HASH_MAGIC);
(void)vdir_add_backend(rr->vd, be, w);
rr->n_backend++;
}
VCL_BACKEND __match_proto__()
......@@ -119,6 +119,6 @@ vmod_hash_backend(const struct vrt_ctx *ctx, struct vmod_directors_hash *rr,
r = vbe32dec(sha256);
r = scalbn(r, -32);
assert(r >= 0 && r <= 1.0);
be = vdir_pick_be(rr->vd, r, rr->nloops);
be = vdir_pick_be(rr->vd, r, rr->n_backend);
return (be);
}
......@@ -45,7 +45,7 @@ struct vmod_directors_random {
unsigned magic;
#define VMOD_DIRECTORS_RANDOM_MAGIC 0x4732d092
struct vdir *vd;
unsigned nloops;
unsigned n_backend;
struct vbitmap *vbm;
};
......@@ -68,7 +68,7 @@ vmod_rr_getfd(const struct director *dir, struct busyobj *bo)
CAST_OBJ_NOTNULL(rr, dir->priv, VMOD_DIRECTORS_RANDOM_MAGIC);
r = scalbn(random(), -31);
assert(r >= 0 && r < 1.0);
be = vdir_pick_be(rr->vd, r, rr->nloops);
be = vdir_pick_be(rr->vd, r, rr->n_backend);
if (be == NULL)
return (NULL);
return (be->getfd(be, bo));
......@@ -87,7 +87,6 @@ vmod_random__init(const struct vrt_ctx *ctx, struct vmod_directors_random **rrp,
AN(rr);
rr->vbm = vbit_init(8);
AN(rr->vbm);
rr->nloops = 3; //
*rrp = rr;
vdir_new(&rr->vd, vcl_name, vmod_rr_healthy, vmod_rr_getfd, rr);
}
......@@ -113,6 +112,7 @@ vmod_random_add_backend(const struct vrt_ctx *ctx,
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
CHECK_OBJ_NOTNULL(rr, VMOD_DIRECTORS_RANDOM_MAGIC);
(void)vdir_add_backend(rr->vd, be, w);
rr->n_backend++;
}
VCL_BACKEND __match_proto__()
......
......@@ -186,7 +186,7 @@ vdir_pick_be(struct vdir *vd, double w, unsigned nloops)
nbe = vd->n_backend;
assert(w >= 0.0 && w < 1.0);
vdir_lock(vd);
for (l = 0; nbe > 0 && tw > 0.0 && l <nloops; l++) {
for (l = 0; nbe > 0 && tw > 0.0 && l < nloops; l++) {
u = vdir_pick_by_weight(vd, w * tw, vbm);
be = vd->backend[u];
CHECK_OBJ_NOTNULL(be, DIRECTOR_MAGIC);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment