[master] 7be8dd9 Turn the vmod_debug demo-rr-director into a real director, and add a test-case where it is used in stackable fashion.
Poul-Henning Kamp
phk at varnish-cache.org
Thu Mar 7 10:19:52 CET 2013
commit 7be8dd9fc8c8e5199715e33aee9137cd6c7acd3e
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date: Thu Mar 7 09:18:44 2013 +0000
Turn the vmod_debug demo-rr-director into a real director, and
add a test-case where it is used in stackable fashion.
I should have done it this way from the very start, rather than
muck about with director configurations in VCC...
diff --git a/bin/varnishtest/tests/m00009.vtc b/bin/varnishtest/tests/m00009.vtc
index b81f07e..c56f2ef 100644
--- a/bin/varnishtest/tests/m00009.vtc
+++ b/bin/varnishtest/tests/m00009.vtc
@@ -35,7 +35,7 @@ varnish v1 -vcl+backend {
}
sub vcl_recv {
- set req.backend = rr.select();
+ set req.backend = rr.backend();
}
} -start
diff --git a/bin/varnishtest/tests/m00010.vtc b/bin/varnishtest/tests/m00010.vtc
new file mode 100644
index 0000000..332d16e
--- /dev/null
+++ b/bin/varnishtest/tests/m00010.vtc
@@ -0,0 +1,75 @@
+varnishtest "Test vmod.debug round robin director"
+
+
+server s1 {
+ rxreq
+ txresp -body "1"
+} -start
+
+server s2 {
+ rxreq
+ txresp -body "22"
+} -start
+
+
+server s3 {
+ rxreq
+ txresp -body "333"
+} -start
+
+server s4 {
+ rxreq
+ txresp -body "4444"
+} -start
+
+
+varnish v1 -vcl+backend {
+
+ import debug from "${topbuild}/lib/libvmod_debug/.libs/libvmod_debug.so" ;
+ sub vcl_init {
+ new rr1 = debug.rr();
+ rr1.add_backend(s1);
+ rr1.add_backend(s3);
+
+ new rr2 = debug.rr();
+ rr2.add_backend(s2);
+ rr2.add_backend(s4);
+
+ new rr3 = debug.rr();
+ rr3.add_backend(rr1.backend());
+ rr3.add_backend(rr2.backend());
+ }
+
+ sub vcl_recv {
+ set req.backend = rr3.backend();
+ }
+} -start
+
+client c1 {
+ timeout 3
+ txreq -url "/foo1"
+ rxresp
+ expect resp.bodylen == 1
+ txreq -url "/foo2"
+ rxresp
+ expect resp.bodylen == 2
+ txreq -url "/foo3"
+ rxresp
+ expect resp.bodylen == 3
+ txreq -url "/foo4"
+ rxresp
+ expect resp.bodylen == 4
+} -run
+
+server s1 -start
+server s2 -start
+
+client c2 {
+ timeout 3
+ txreq -url "/foo11"
+ rxresp
+ expect resp.bodylen == 1
+ txreq -url "/foo22"
+ rxresp
+ expect resp.bodylen == 2
+} -run
diff --git a/lib/libvmod_debug/vmod.vcc b/lib/libvmod_debug/vmod.vcc
index 97d5f5e..8451c6c 100644
--- a/lib/libvmod_debug/vmod.vcc
+++ b/lib/libvmod_debug/vmod.vcc
@@ -38,5 +38,5 @@ Object obj(STRING) {
Object rr() {
Method VOID .add_backend(BACKEND)
- Method BACKEND .select()
+ Method BACKEND .backend()
}
diff --git a/lib/libvmod_debug/vmod_debug_rr.c b/lib/libvmod_debug/vmod_debug_rr.c
index 186e2a1..a326051 100644
--- a/lib/libvmod_debug/vmod_debug_rr.c
+++ b/lib/libvmod_debug/vmod_debug_rr.c
@@ -31,6 +31,7 @@
#include <stdlib.h>
#include "cache/cache.h"
+#include "cache/cache_backend.h"
#include "vrt.h"
#include "vcc_if.h"
@@ -46,16 +47,58 @@ struct vmod_debug_rr {
unsigned magic;
#define VMOD_DEBUG_RR_MAGIC 0x99f4b726
VTAILQ_HEAD(, vmod_debug_rr_entry) listhead;
+ int nbe;
pthread_mutex_t mtx;
+ struct director *dir;
};
+static unsigned
+vmod_rr_healthy(const struct director *dir, const struct req *req)
+{
+ struct vmod_debug_rr_entry *ep;
+ struct vmod_debug_rr *rr;
+ unsigned retval = 0;
+
+ CAST_OBJ_NOTNULL(rr, dir->priv, VMOD_DEBUG_RR_MAGIC);
+ AZ(pthread_mutex_lock(&rr->mtx));
+ VTAILQ_FOREACH(ep, &rr->listhead, list) {
+ if (ep->be->healthy(ep->be, req)) {
+ retval = 1;
+ break;
+ }
+ }
+ AZ(pthread_mutex_unlock(&rr->mtx));
+ return (retval);
+}
+
+static struct vbc *
+vmod_rr_getfd(const struct director *dir, struct req *req)
+{
+ struct vmod_debug_rr_entry *ep = NULL;
+ struct vmod_debug_rr *rr;
+ int i;
+
+ CAST_OBJ_NOTNULL(rr, dir->priv, VMOD_DEBUG_RR_MAGIC);
+ AZ(pthread_mutex_lock(&rr->mtx));
+ for (i = 0; i < rr->nbe; i++) {
+ ep = VTAILQ_FIRST(&rr->listhead);
+ VTAILQ_REMOVE(&rr->listhead, ep, list);
+ VTAILQ_INSERT_TAIL(&rr->listhead, ep, list);
+ if (ep->be->healthy(ep->be, req))
+ break;
+ }
+ AZ(pthread_mutex_unlock(&rr->mtx));
+ if (i == rr->nbe || ep == NULL)
+ return (NULL);
+ return (ep->be->getfd(ep->be, req));
+}
+
VCL_VOID
vmod_rr__init(struct req *req, struct vmod_debug_rr **rrp, const char *vcl_name)
{
struct vmod_debug_rr *rr;
(void)req;
- (void)vcl_name;
AN(rrp);
AZ(*rrp);
@@ -64,6 +107,12 @@ vmod_rr__init(struct req *req, struct vmod_debug_rr **rrp, const char *vcl_name)
*rrp = rr;
AZ(pthread_mutex_init(&rr->mtx, NULL));
VTAILQ_INIT(&rr->listhead);
+ ALLOC_OBJ(rr->dir, DIRECTOR_MAGIC);
+ AN(rr->dir);
+ REPLACE(rr->dir->vcl_name, vcl_name);
+ rr->dir->priv = rr;
+ rr->dir->healthy = vmod_rr_healthy;
+ rr->dir->getfd = vmod_rr_getfd;
}
VCL_VOID
@@ -84,7 +133,9 @@ vmod_rr__fini(struct req *req, struct vmod_debug_rr **rrp)
VTAILQ_REMOVE(&rr->listhead, ep, list);
FREE_OBJ(ep);
}
- FREE_OBJ(*rrp);
+ REPLACE(rr->dir->vcl_name, NULL);
+ FREE_OBJ(rr->dir);
+ FREE_OBJ(rr);
}
VCL_VOID
@@ -98,21 +149,13 @@ vmod_rr_add_backend(struct req *req, struct vmod_debug_rr * rr, VCL_BACKEND be)
ep->be = be;
AZ(pthread_mutex_lock(&rr->mtx));
VTAILQ_INSERT_TAIL(&rr->listhead, ep, list);
+ rr->nbe++;
AZ(pthread_mutex_unlock(&rr->mtx));
}
-VCL_BACKEND
-vmod_rr_select(struct req *req, struct vmod_debug_rr *rr)
+VCL_BACKEND __match_proto__()
+vmod_rr_backend(struct req *req, struct vmod_debug_rr *rr)
{
- struct vmod_debug_rr_entry *ep;
-
(void)req;
-
- CHECK_OBJ_NOTNULL(rr, VMOD_DEBUG_RR_MAGIC);
- AZ(pthread_mutex_lock(&rr->mtx));
- ep = VTAILQ_FIRST(&rr->listhead);
- VTAILQ_REMOVE(&rr->listhead, ep, list);
- VTAILQ_INSERT_TAIL(&rr->listhead, ep, list);
- AZ(pthread_mutex_unlock(&rr->mtx));
- return (ep->be);
+ return (rr->dir);
}
More information about the varnish-commit
mailing list