Hi,
It turns out my trainees were so quiet during exercises that I could
explore this a bit more.
I have come to the point where you don't need a backend declaration in
your VCL, as long as you have a director that will dynamically create
one. Once backend check was deferred to *after* vcl_init, it made very
easy to allow a director to become the default backend.
See the test d00007.vtc for a pure dynamic backend:
varnish v1 -vcl {
import ${vmod_debug};
sub vcl_init {
new s1 = debug.dyn("${s1_addr}", "${s1_port}");
}
} -start
See the test d00008.vtc for a director as the default:
varnish v1 -vcl+backend {
import ${vmod_directors};
# no need for `set bereq.backend = default;`
sub vcl_init {
new default = directors.round_robin();
default.add_backend(s1);
default.add_backend(s2);
}
} -start
There are still caveats with the current implementation, and it's still not
enough to implement a new dns director. Dynamically created backend
won't receive events, which is not a problem *so far* since we can't pass
probes to VMODs yet. Instead of emitting per-backend code for events,
it could rely on backend_find() to fire events on both static and dynamic
backends.
Comments?
Cheers,
Dridi
On Mon, Apr 13, 2015 at 10:17 AM, Dridi Boukelmoune <[email protected]> wrote:
> Hi,
>
> It turned out you couldn't properly create backends dynamically, or at
> least remove them. Please find attached a patch set that fixes that,
> and adds a "director" capability to the debug vmod with an initial
> test case. This is still incomplete, and I want to push this further. For
> example I've created a Backend_added log record, but nothing for
> deletion.
>
> Before I do anything else, I'll wait for feedback :)
>
> Cheers,
> Dridi
>
> PS. today I'm doing training and the customer is blocking IRC
From f3dac3ac5aef87a60f350a81e2fb8705b1e08894 Mon Sep 17 00:00:00 2001
From: Dridi Boukelmoune <[email protected]>
Date: Tue, 14 Apr 2015 11:27:49 +0200
Subject: [PATCH 4/7] Rename static function VCL_Load to vcl_load
---
bin/varnishd/cache/cache_vcl.c | 4 ++--
doc/graphviz/cache_req_fsm.dot | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/bin/varnishd/cache/cache_vcl.c b/bin/varnishd/cache/cache_vcl.c
index a5a7da4..8df784e 100644
--- a/bin/varnishd/cache/cache_vcl.c
+++ b/bin/varnishd/cache/cache_vcl.c
@@ -191,7 +191,7 @@ vcl_set_state(struct vcls *vcl, const char *state)
}
static int
-VCL_Load(struct cli *cli, const char *name, const char *fn, const char *state)
+vcl_load(struct cli *cli, const char *name, const char *fn, const char *state)
{
struct vcls *vcl;
struct VCL_conf const *cnf;
@@ -345,7 +345,7 @@ ccf_config_load(struct cli *cli, const char * const *av, void *priv)
AZ(priv);
ASSERT_CLI();
- if (VCL_Load(cli, av[2], av[3], av[4]))
+ if (vcl_load(cli, av[2], av[3], av[4]))
VCLI_SetResult(cli, CLIS_PARAM);
return;
}
diff --git a/doc/graphviz/cache_req_fsm.dot b/doc/graphviz/cache_req_fsm.dot
index 5856984..4c29d0a 100644
--- a/doc/graphviz/cache_req_fsm.dot
+++ b/doc/graphviz/cache_req_fsm.dot
@@ -28,7 +28,7 @@ digraph cache_req_fsm {
init [
shape=record
label="
- {VCL_Load:|
+ {vcl_load:|
{vcl_init}|
{<ok>ok|<fail>fail}}"
]
--
2.1.0
From 825aa8b3f61842afd13e6175d51d2cff1ed749b4 Mon Sep 17 00:00:00 2001
From: Dridi Boukelmoune <[email protected]>
Date: Tue, 14 Apr 2015 15:22:40 +0200
Subject: [PATCH 5/7] Defer backend existence check after vcl_init{}
At this point you still need to declare a backend anyway.
---
bin/varnishd/cache/cache_vcl.c | 13 +++++++++++++
lib/libvcc/vcc_compile.c | 21 +++++++--------------
lib/libvmod_debug/vmod_debug_dyn.c | 1 +
3 files changed, 21 insertions(+), 14 deletions(-)
diff --git a/bin/varnishd/cache/cache_vcl.c b/bin/varnishd/cache/cache_vcl.c
index 8df784e..f7a3f82 100644
--- a/bin/varnishd/cache/cache_vcl.c
+++ b/bin/varnishd/cache/cache_vcl.c
@@ -257,6 +257,19 @@ vcl_load(struct cli *cli, const char *name, const char *fn, const char *state)
FREE_OBJ(vcl);
return (1);
}
+ if (vcl->conf->director[0] == NULL) {
+ assert(vcl->conf->ndirector == 1);
+ VCLI_Out(cli,
+ "No backends or directors found in VCL program, "
+ "at least one is necessary after vcl_init{}.");
+ /* XXX below is dirty copy/paste */
+ ctx.method = VCL_MET_FINI;
+ (void)vcl->conf->fini_func(&ctx);
+ AZ(vcl->conf->event_vcl(&ctx, VCL_EVENT_DISCARD));
+ (void)dlclose(vcl->dlh);
+ FREE_OBJ(vcl);
+ return (1);
+ }
vcl_set_state(vcl, state);
assert(hand == VCL_RET_OK);
VCLI_Out(cli, "Loaded \"%s\" as \"%s\"", fn , name);
diff --git a/lib/libvcc/vcc_compile.c b/lib/libvcc/vcc_compile.c
index f651ed7..c1a9299 100644
--- a/lib/libvcc/vcc_compile.c
+++ b/lib/libvcc/vcc_compile.c
@@ -664,22 +664,15 @@ vcc_CompileSource(const struct vcc *tl0, struct vsb *sb, struct source *sp)
if (tl->err)
return (vcc_DestroyTokenList(tl, NULL));
- /* Check if we have any backends at all */
- if (tl->ndirector == 1) {
- VSB_printf(tl->sb,
- "No backends or directors found in VCL program, "
- "at least one is necessary.\n");
- tl->err = 1;
- return (vcc_DestroyTokenList(tl, NULL));
+ /* Configure the default director, if any at this point */
+ if (tl->ndirector > 1) {
+ ifp = New_IniFin(tl);
+ VSB_printf(ifp->ini,
+ "\tVCL_conf.director[0] = VCL_conf.director[%d];",
+ tl->defaultdir);
+ vcc_AddRef(tl, tl->t_defaultdir, SYM_BACKEND);
}
- /* Configure the default director */
- ifp = New_IniFin(tl);
- VSB_printf(ifp->ini,
- "\tVCL_conf.director[0] = VCL_conf.director[%d];",
- tl->defaultdir);
- vcc_AddRef(tl, tl->t_defaultdir, SYM_BACKEND);
-
/* Check for orphans */
if (vcc_CheckReferences(tl))
return (vcc_DestroyTokenList(tl, NULL));
diff --git a/lib/libvmod_debug/vmod_debug_dyn.c b/lib/libvmod_debug/vmod_debug_dyn.c
index 342ca5e..6d1a761 100644
--- a/lib/libvmod_debug/vmod_debug_dyn.c
+++ b/lib/libvmod_debug/vmod_debug_dyn.c
@@ -98,6 +98,7 @@ vmod_dyn__fini(struct vmod_debug_dyn **op)
CAST_OBJ_NOTNULL(o, *op, VMOD_DEBUG_DYN_MAGIC);
CHECK_OBJ_NOTNULL(&o->vrt, VRT_BACKEND_MAGIC);
AN(o->dir);
+ VRT_event_vbe(VCL_EVENT_COLD, o->dir, &o->vrt);
VRT_fini_vbe(&o->dir, &o->vrt);
AZ(o->dir);
free(o->addr);
--
2.1.0
From a5e57056607c8c7e3de17f280dd0d3f0494faa83 Mon Sep 17 00:00:00 2001
From: Dridi Boukelmoune <[email protected]>
Date: Tue, 14 Apr 2015 16:09:38 +0200
Subject: [PATCH 6/7] VCL doesn't require static backends anymore
---
bin/varnishd/cache/cache_backend.c | 20 ++++++++++++++++++++
bin/varnishtest/tests/d00007.vtc | 11 +----------
include/vrt.h | 1 +
lib/libvmod_debug/vmod_debug_dyn.c | 1 +
4 files changed, 23 insertions(+), 10 deletions(-)
diff --git a/bin/varnishd/cache/cache_backend.c b/bin/varnishd/cache/cache_backend.c
index 3ec17d7..35c9103 100644
--- a/bin/varnishd/cache/cache_backend.c
+++ b/bin/varnishd/cache/cache_backend.c
@@ -373,3 +373,23 @@ VRT_fini_vbe(struct director **dp, const struct vrt_backend *vrt)
free(d->vcl_name);
FREE_OBJ(d);
}
+
+/*--------------------------------------------------------------------
+ * This function uses the specified director as the default one if relevant.
+ */
+
+void
+VRT_event_vdi(VRT_CTX, struct director *dir)
+{
+ ASSERT_CLI();
+ CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
+ CHECK_OBJ_NOTNULL(dir, DIRECTOR_MAGIC);
+
+ if (ctx->vcl->director[0] == NULL ||
+ !strcmp("default", dir->vcl_name)) {
+ VSL(SLT_Debug, 0, "Registered director %s", dir->vcl_name);
+ ctx->vcl->director[0] = dir;
+ }
+
+ AN(ctx->vcl->director[0]);
+}
diff --git a/bin/varnishtest/tests/d00007.vtc b/bin/varnishtest/tests/d00007.vtc
index 4695514..250dcb3 100644
--- a/bin/varnishtest/tests/d00007.vtc
+++ b/bin/varnishtest/tests/d00007.vtc
@@ -8,25 +8,16 @@ server s1 {
varnish v1 -vcl {
import ${vmod_debug};
- backend dummy {
- .host = "${bad_ip}";
- }
-
sub vcl_init {
new s1 = debug.dyn("${s1_addr}", "${s1_port}");
}
-
- sub vcl_recv {
- set req.backend_hint = s1.backend();
- }
} -start
logexpect l1 -v v1 -g raw -d {
- expect * 0 Backend_added "dummy vcl1.dummy"
expect * 0 Backend_added "s1 vcl1.s1"
} -start
-varnish v1 -expect MAIN.n_backend == 2
+varnish v1 -expect MAIN.n_backend == 1
logexpect l1 -wait
diff --git a/include/vrt.h b/include/vrt.h
index b5442d8..a0fc083 100644
--- a/include/vrt.h
+++ b/include/vrt.h
@@ -238,6 +238,7 @@ void VRT_event_vbe(enum vcl_event_e, const struct director *,
const struct vrt_backend *);
#endif
void VRT_fini_vbe(struct director **, const struct vrt_backend *);
+void VRT_event_vdi(VRT_CTX, struct director *dir);
/* Suckaddr related */
int VRT_VSA_GetPtr(const struct suckaddr *sua, const unsigned char ** dst);
diff --git a/lib/libvmod_debug/vmod_debug_dyn.c b/lib/libvmod_debug/vmod_debug_dyn.c
index 6d1a761..106b568 100644
--- a/lib/libvmod_debug/vmod_debug_dyn.c
+++ b/lib/libvmod_debug/vmod_debug_dyn.c
@@ -87,6 +87,7 @@ vmod_dyn__init(VRT_CTX, struct vmod_debug_dyn **op,
*op = o;
VRT_event_vbe(VCL_EVENT_WARM, o->dir, &o->vrt);
+ VRT_event_vdi(ctx, o->dir);
}
VCL_VOID
--
2.1.0
From f4598639bfe890231b3a8d87a82d29c735e2864f Mon Sep 17 00:00:00 2001
From: Dridi Boukelmoune <[email protected]>
Date: Tue, 14 Apr 2015 16:52:31 +0200
Subject: [PATCH 7/7] Built-in directors now register themselves
And can be the default director if named "default".
---
bin/varnishtest/tests/d00008.vtc | 31 +++++++++++++++++++++++++++++++
lib/libvmod_directors/fall_back.c | 2 +-
lib/libvmod_directors/hash.c | 2 +-
lib/libvmod_directors/random.c | 4 ++--
lib/libvmod_directors/round_robin.c | 2 +-
lib/libvmod_directors/vdir.c | 5 +++--
lib/libvmod_directors/vdir.h | 4 ++--
7 files changed, 41 insertions(+), 9 deletions(-)
create mode 100644 bin/varnishtest/tests/d00008.vtc
diff --git a/bin/varnishtest/tests/d00008.vtc b/bin/varnishtest/tests/d00008.vtc
new file mode 100644
index 0000000..9419387
--- /dev/null
+++ b/bin/varnishtest/tests/d00008.vtc
@@ -0,0 +1,31 @@
+varnishtest "Test a director as a default backend"
+
+server s1 {
+ rxreq
+ txresp -hdr "backend: s1"
+} -start
+
+server s2 {
+ rxreq
+ txresp -hdr "backend: s2"
+} -start
+
+varnish v1 -vcl+backend {
+ import ${vmod_directors};
+
+ # no need for `set bereq.backend = default;`
+ sub vcl_init {
+ new default = directors.round_robin();
+ default.add_backend(s1);
+ default.add_backend(s2);
+ }
+} -start
+
+client c1 {
+ txreq -url "/foo1"
+ rxresp
+ expect resp.http.backend == "s1"
+ txreq -url "/foo2"
+ rxresp
+ expect resp.http.backend == "s2"
+} -run
diff --git a/lib/libvmod_directors/fall_back.c b/lib/libvmod_directors/fall_back.c
index 77ec45c..f4d81fb 100644
--- a/lib/libvmod_directors/fall_back.c
+++ b/lib/libvmod_directors/fall_back.c
@@ -91,7 +91,7 @@ vmod_fallback__init(VRT_CTX,
ALLOC_OBJ(rr, VMOD_DIRECTORS_FALLBACK_MAGIC);
AN(rr);
*rrp = rr;
- vdir_new(&rr->vd, vcl_name, vmod_fallback_healthy,
+ vdir_new(ctx, &rr->vd, vcl_name, vmod_fallback_healthy,
vmod_fallback_resolve, rr);
}
diff --git a/lib/libvmod_directors/hash.c b/lib/libvmod_directors/hash.c
index c3def17..4d43309 100644
--- a/lib/libvmod_directors/hash.c
+++ b/lib/libvmod_directors/hash.c
@@ -64,7 +64,7 @@ vmod_hash__init(VRT_CTX, struct vmod_directors_hash **rrp,
rr->vbm = vbit_init(8);
AN(rr->vbm);
*rrp = rr;
- vdir_new(&rr->vd, vcl_name, NULL, NULL, rr);
+ vdir_new(ctx, &rr->vd, vcl_name, NULL, NULL, rr);
}
VCL_VOID __match_proto__()
diff --git a/lib/libvmod_directors/random.c b/lib/libvmod_directors/random.c
index a0612f3..761025f 100644
--- a/lib/libvmod_directors/random.c
+++ b/lib/libvmod_directors/random.c
@@ -87,8 +87,8 @@ vmod_random__init(VRT_CTX, struct vmod_directors_random **rrp,
ALLOC_OBJ(rr, VMOD_DIRECTORS_RANDOM_MAGIC);
AN(rr);
*rrp = rr;
- vdir_new(&rr->vd, vcl_name, vmod_random_healthy, vmod_random_resolve,
- rr);
+ vdir_new(ctx, &rr->vd, vcl_name, vmod_random_healthy,
+ vmod_random_resolve, rr);
}
VCL_VOID __match_proto__()
diff --git a/lib/libvmod_directors/round_robin.c b/lib/libvmod_directors/round_robin.c
index be92545..49a8ad5 100644
--- a/lib/libvmod_directors/round_robin.c
+++ b/lib/libvmod_directors/round_robin.c
@@ -94,7 +94,7 @@ vmod_round_robin__init(VRT_CTX,
ALLOC_OBJ(rr, VMOD_DIRECTORS_ROUND_ROBIN_MAGIC);
AN(rr);
*rrp = rr;
- vdir_new(&rr->vd, vcl_name, vmod_rr_healthy, vmod_rr_resolve, rr);
+ vdir_new(ctx, &rr->vd, vcl_name, vmod_rr_healthy, vmod_rr_resolve, rr);
}
VCL_VOID __match_proto__()
diff --git a/lib/libvmod_directors/vdir.c b/lib/libvmod_directors/vdir.c
index 938d6de..9ee900a 100644
--- a/lib/libvmod_directors/vdir.c
+++ b/lib/libvmod_directors/vdir.c
@@ -51,8 +51,8 @@ vdir_expand(struct vdir *vd, unsigned n)
}
void
-vdir_new(struct vdir **vdp, const char *vcl_name, vdi_healthy_f *healthy,
- vdi_resolve_f *resolve, void *priv)
+vdir_new(VRT_CTX, struct vdir **vdp, const char *vcl_name,
+ vdi_healthy_f *healthy, vdi_resolve_f *resolve, void *priv)
{
struct vdir *vd;
@@ -72,6 +72,7 @@ vdir_new(struct vdir **vdp, const char *vcl_name, vdi_healthy_f *healthy,
vd->dir->resolve = resolve;
vd->vbm = vbit_init(8);
AN(vd->vbm);
+ VRT_event_vdi(ctx, vd->dir);
}
void
diff --git a/lib/libvmod_directors/vdir.h b/lib/libvmod_directors/vdir.h
index 9214911..b46e16a 100644
--- a/lib/libvmod_directors/vdir.h
+++ b/lib/libvmod_directors/vdir.h
@@ -41,8 +41,8 @@ struct vdir {
struct vbitmap *vbm;
};
-void vdir_new(struct vdir **vdp, const char *vcl_name, vdi_healthy_f *healthy,
- vdi_resolve_f *resolve, void *priv);
+void vdir_new(VRT_CTX, struct vdir **vdp, const char *vcl_name,
+ vdi_healthy_f *healthy, vdi_resolve_f *resolve, void *priv);
void vdir_delete(struct vdir **vdp);
void vdir_lock(struct vdir *vd);
void vdir_unlock(struct vdir *vd);
--
2.1.0
_______________________________________________
varnish-dev mailing list
[email protected]
https://www.varnish-cache.org/lists/mailman/listinfo/varnish-dev