[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