r2943 - in trunk/varnish-cache: bin/varnishd bin/varnishtest/tests include lib/libvcl

petter at projects.linpro.no petter at projects.linpro.no
Mon Jul 14 14:59:10 CEST 2008


Author: petter
Date: 2008-07-14 14:59:10 +0200 (Mon, 14 Jul 2008)
New Revision: 2943

Added:
   trunk/varnish-cache/bin/varnishd/cache_dir_round_robin.c
   trunk/varnish-cache/bin/varnishtest/tests/v00009.vtc
   trunk/varnish-cache/lib/libvcl/vcc_dir_round_robin.c
Modified:
   trunk/varnish-cache/bin/varnishd/Makefile.am
   trunk/varnish-cache/include/vrt.h
   trunk/varnish-cache/lib/libvcl/Makefile.am
   trunk/varnish-cache/lib/libvcl/vcc_backend.c
   trunk/varnish-cache/lib/libvcl/vcc_compile.h
   trunk/varnish-cache/lib/libvcl/vcc_fixed_token.c
Log:
Added a round robin director. The round robin director can be created like this:

director batman round-robin {
	{ .backend = b1; }
	{ .backend = b2; }
	{ .backend = b3; }
}

sub vcl_recv {
	set req.backend = batman;
}

The backend will then be chosen in a round robin fashion.



Modified: trunk/varnish-cache/bin/varnishd/Makefile.am
===================================================================
--- trunk/varnish-cache/bin/varnishd/Makefile.am	2008-07-11 22:13:29 UTC (rev 2942)
+++ trunk/varnish-cache/bin/varnishd/Makefile.am	2008-07-14 12:59:10 UTC (rev 2943)
@@ -18,6 +18,7 @@
 	cache_center.c \
 	cache_cli.c \
 	cache_dir_random.c \
+	cache_dir_round_robin.c \
 	cache_dir_simple.c \
 	cache_expire.c \
 	cache_fetch.c \

Added: trunk/varnish-cache/bin/varnishd/cache_dir_round_robin.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_dir_round_robin.c	                        (rev 0)
+++ trunk/varnish-cache/bin/varnishd/cache_dir_round_robin.c	2008-07-14 12:59:10 UTC (rev 2943)
@@ -0,0 +1,127 @@
+/*-
+ * Copyright (c) 2006 Verdens Gang AS
+ * Copyright (c) 2006-2008 Linpro AS
+ * All rights reserved.
+ *
+ * Author: Petter Knudsen <petter at linpro.no>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: cache_dir_round_robin.c 2906 2008-07-08 10:29:07Z phk $
+ *
+ */
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "shmlog.h"
+#include "cache.h"
+#include "vrt.h"
+
+/*--------------------------------------------------------------------*/
+
+struct vdi_round_robin_host {
+	struct backend		*backend;
+};
+
+struct vdi_round_robin {
+	unsigned		magic;
+#define VDI_ROUND_ROBIN_MAGIC	0x2114a178
+	struct director		dir;
+	struct backend		*backend;
+	struct vdi_round_robin_host	*hosts;
+	unsigned		nhosts;
+	unsigned		next_host;
+};
+
+
+static struct backend *
+vdi_round_robin_choose(struct sess *sp)
+{
+	struct vdi_round_robin *vs;
+	struct backend *backend;
+
+	CHECK_OBJ_NOTNULL(sp->director, DIRECTOR_MAGIC);
+	CAST_OBJ_NOTNULL(vs, sp->director->priv, VDI_ROUND_ROBIN_MAGIC);
+
+	backend = vs->hosts[ vs->next_host ].backend;
+	vs->next_host = (vs->next_host + 1) % vs->nhosts;
+
+	return (backend);
+}
+
+static void
+vdi_round_robin_fini(struct director *d)
+{
+	int i;
+	struct vdi_round_robin *vs;
+	struct vdi_round_robin_host *vh;
+
+	CHECK_OBJ_NOTNULL(d, DIRECTOR_MAGIC);
+	CAST_OBJ_NOTNULL(vs, d->priv, VDI_ROUND_ROBIN_MAGIC);
+	
+	vh = vs->hosts;
+	for (i = 0; i < vs->nhosts; i++, vh++)
+		VBE_DropRef(vh->backend);
+	free(vs->hosts);
+	vs->dir.magic = 0;
+	vs->next_host = 0;
+	FREE_OBJ(vs);
+}
+
+void
+VRT_init_dir_round_robin(struct cli *cli, struct director **bp, const struct vrt_dir_round_robin *t)
+{
+	struct vdi_round_robin *vs;
+	const struct vrt_dir_round_robin_entry *te;
+	struct vdi_round_robin_host *vh;
+	int i;
+	
+	(void)cli;
+
+	ALLOC_OBJ(vs, VDI_ROUND_ROBIN_MAGIC);
+	XXXAN(vs);
+	vs->hosts = calloc(sizeof *vh, t->nmember);
+	XXXAN(vs->hosts);
+
+	vs->dir.magic = DIRECTOR_MAGIC;
+	vs->dir.priv = vs;
+	vs->dir.name = "round_robin";
+	vs->dir.choose = vdi_round_robin_choose;
+	vs->dir.fini = vdi_round_robin_fini;
+
+	vh = vs->hosts;
+	te = t->members;
+	for (i = 0; i < t->nmember; i++, vh++, te++)
+		vh->backend = VBE_AddBackend(cli, te->host);
+	vs->nhosts = t->nmember;
+	vs->next_host = 0;
+
+	*bp = &vs->dir;
+}

Added: trunk/varnish-cache/bin/varnishtest/tests/v00009.vtc
===================================================================
--- trunk/varnish-cache/bin/varnishtest/tests/v00009.vtc	                        (rev 0)
+++ trunk/varnish-cache/bin/varnishtest/tests/v00009.vtc	2008-07-14 12:59:10 UTC (rev 2943)
@@ -0,0 +1,67 @@
+# $Id$
+
+test "Test round robin director"
+
+server s1 -listen 127.0.0.1:2000 {
+	rxreq
+	txresp -body "1"
+} -start
+
+server s2 -listen 127.0.0.1:3000 {
+	rxreq
+	txresp -body "22"
+} -start
+
+
+server s3 -listen 127.0.0.1:4000 {
+	rxreq
+	txresp -body "333"
+} -start
+
+server s4 -listen 127.0.0.1:5000 {
+	rxreq
+	txresp -body "4444"
+} -start
+
+
+varnish v1 -vcl+backend {
+	director batman round-robin {
+		{ .backend = s1; }
+		{ .backend = s2; }
+		{ .backend = s3; }
+		{ .backend = s4; }
+	}
+
+	sub vcl_recv {
+		set req.backend = batman;
+	}
+} -start
+
+client c1 {
+	timeout 3
+	txreq -url "/foo1"
+	rxresp
+	expect resp.http.content-length == 1
+	txreq -url "/foo2"
+	rxresp
+	expect resp.http.content-length == 2
+	txreq -url "/foo3"
+	rxresp
+	expect resp.http.content-length == 3
+	txreq -url "/foo4"
+	rxresp
+	expect resp.http.content-length == 4
+} -run
+
+server s1 -start
+server s2 -start
+
+client c2 {
+	timeout 3
+	txreq -url "/foo11"
+	rxresp
+	expect resp.http.content-length == 1
+	txreq -url "/foo22"
+	rxresp
+	expect resp.http.content-length == 2
+} -run

Modified: trunk/varnish-cache/include/vrt.h
===================================================================
--- trunk/varnish-cache/include/vrt.h	2008-07-11 22:13:29 UTC (rev 2942)
+++ trunk/varnish-cache/include/vrt.h	2008-07-14 12:59:10 UTC (rev 2943)
@@ -92,6 +92,21 @@
 };
 
 /*
+ * A director with round robin selection
+ */
+
+struct vrt_dir_round_robin_entry {
+	const struct vrt_backend		*host;
+};
+
+struct vrt_dir_round_robin {
+	const char				*name;
+	unsigned 				nmember;
+	const struct vrt_dir_round_robin_entry	*members;
+};
+
+
+/*
  * other stuff.
  * XXX: document when bored
  */
@@ -147,6 +162,7 @@
 /* Backend related */
 void VRT_init_dir_simple(struct cli *, struct director **, const struct vrt_dir_simple *);
 void VRT_init_dir_random(struct cli *, struct director **, const struct vrt_dir_random *);
+void VRT_init_dir_round_robin(struct cli *, struct director **, const struct vrt_dir_round_robin *);
 void VRT_fini_dir(struct cli *, struct director *);
 
 char *VRT_IP_string(const struct sess *sp, const struct sockaddr *sa);

Modified: trunk/varnish-cache/lib/libvcl/Makefile.am
===================================================================
--- trunk/varnish-cache/lib/libvcl/Makefile.am	2008-07-11 22:13:29 UTC (rev 2942)
+++ trunk/varnish-cache/lib/libvcl/Makefile.am	2008-07-14 12:59:10 UTC (rev 2943)
@@ -14,6 +14,7 @@
 	vcc_backend.c \
 	vcc_compile.c \
 	vcc_dir_random.c \
+	vcc_dir_round_robin.c \
 	vcc_parse.c \
 	vcc_fixed_token.c \
 	vcc_obj.c \

Modified: trunk/varnish-cache/lib/libvcl/vcc_backend.c
===================================================================
--- trunk/varnish-cache/lib/libvcl/vcc_backend.c	2008-07-11 22:13:29 UTC (rev 2942)
+++ trunk/varnish-cache/lib/libvcl/vcc_backend.c	2008-07-14 12:59:10 UTC (rev 2943)
@@ -656,6 +656,7 @@
 	parsedirector_f	*func;
 } dirlist[] = {
 	{ "random", 	vcc_ParseRandomDirector },
+	{ "round-robin", 	vcc_ParseRoundRobinDirector },
 	{ NULL,		NULL }
 };
 

Modified: trunk/varnish-cache/lib/libvcl/vcc_compile.h
===================================================================
--- trunk/varnish-cache/lib/libvcl/vcc_compile.h	2008-07-11 22:13:29 UTC (rev 2942)
+++ trunk/varnish-cache/lib/libvcl/vcc_compile.h	2008-07-14 12:59:10 UTC (rev 2943)
@@ -178,6 +178,9 @@
 /* vcc_dir_random.c */
 parsedirector_f vcc_ParseRandomDirector;
 
+/* vcc_dir_round_robin.c */
+parsedirector_f vcc_ParseRoundRobinDirector;
+
 /* vcc_obj.c */
 extern struct var vcc_vars[];
 

Added: trunk/varnish-cache/lib/libvcl/vcc_dir_round_robin.c
===================================================================
--- trunk/varnish-cache/lib/libvcl/vcc_dir_round_robin.c	                        (rev 0)
+++ trunk/varnish-cache/lib/libvcl/vcc_dir_round_robin.c	2008-07-14 12:59:10 UTC (rev 2943)
@@ -0,0 +1,108 @@
+/*-
+ * Copyright (c) 2006 Verdens Gang AS
+ * Copyright (c) 2006-2008 Linpro AS
+ * All rights reserved.
+ *
+ * Author: Petter Knudsen <petter at linpro.no>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: vcc_dir_random.c 2900 2008-07-08 07:30:42Z phk $
+ */
+
+#include "config.h"
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <netdb.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+
+#include "vsb.h"
+
+#include "vcc_priv.h"
+#include "vcc_compile.h"
+#include "libvarnish.h"
+
+/*--------------------------------------------------------------------
+ * Parse directors
+ */
+
+void
+vcc_ParseRoundRobinDirector(struct tokenlist *tl, const struct token *t_policy, const struct token *t_dir)
+{
+	struct token *t_field, *t_be;
+	int nbh, nelem;
+	struct fld_spec *fs;
+
+	fs = vcc_FldSpec(tl, "!backend", NULL);
+
+	Fc(tl, 0,
+	    "\nstatic const struct vrt_dir_round_robin_entry vdrre_%.*s[] = {\n",
+	    PF(t_dir));
+
+	for (nelem = 0; tl->t->tok != '}'; nelem++) {	/* List of members */
+		t_be = tl->t;
+		vcc_ResetFldSpec(fs);
+		nbh = -1;
+
+		ExpectErr(tl, '{');
+		vcc_NextToken(tl);
+		Fc(tl, 0, "\t{");
+	
+		while (tl->t->tok != '}') {	/* Member fields */
+			vcc_IsField(tl, &t_field, fs);
+			ERRCHK(tl);
+			if (vcc_IdIs(t_field, "backend")) {
+				vcc_ParseBackendHost(tl, &nbh,
+				    t_dir, t_policy, nelem);
+				Fc(tl, 0, " .host = &bh_%d,", nbh);
+				ERRCHK(tl);
+			} else {
+				ErrInternal(tl);
+			}
+		}
+		vcc_FieldsOk(tl, fs);
+		if (tl->err) {
+			vsb_printf(tl->sb,
+			    "\nIn member host specfication starting at:\n");
+			vcc_ErrWhere(tl, t_be);
+			return;
+		}
+		Fc(tl, 0, " },\n");
+		vcc_NextToken(tl);
+	}
+	Fc(tl, 0, "};\n");
+	Fc(tl, 0,
+	    "\nstatic const struct vrt_dir_round_robin vdrr_%.*s = {\n",
+	    PF(t_dir));
+	Fc(tl, 0, "\t.name = \"%.*s\",\n", PF(t_dir));
+	Fc(tl, 0, "\t.nmember = %d,\n", nelem);
+	Fc(tl, 0, "\t.members = vdrre_%.*s,\n", PF(t_dir));
+	Fc(tl, 0, "};\n");
+	Fi(tl, 0,
+	    "\tVRT_init_dir_round_robin(cli, &VGC_backend_%.*s , &vdrr_%.*s);\n",
+	    PF(t_dir), PF(t_dir));
+	Ff(tl, 0, "\tVRT_fini_dir(cli, VGC_backend_%.*s);\n", PF(t_dir));
+}

Modified: trunk/varnish-cache/lib/libvcl/vcc_fixed_token.c
===================================================================
--- trunk/varnish-cache/lib/libvcl/vcc_fixed_token.c	2008-07-11 22:13:29 UTC (rev 2942)
+++ trunk/varnish-cache/lib/libvcl/vcc_fixed_token.c	2008-07-14 12:59:10 UTC (rev 2943)
@@ -430,6 +430,21 @@
 	vsb_cat(sb, "};\n");
 	vsb_cat(sb, "\n");
 	vsb_cat(sb, "/*\n");
+	vsb_cat(sb, " * A director with round robin selection\n");
+	vsb_cat(sb, " */\n");
+	vsb_cat(sb, "\n");
+	vsb_cat(sb, "struct vrt_dir_round_robin_entry {\n");
+	vsb_cat(sb, "	const struct vrt_backend		*host;\n");
+	vsb_cat(sb, "};\n");
+	vsb_cat(sb, "\n");
+	vsb_cat(sb, "struct vrt_dir_round_robin {\n");
+	vsb_cat(sb, "	const char				*name;\n");
+	vsb_cat(sb, "	unsigned 				nmember;\n");
+	vsb_cat(sb, "	const struct vrt_dir_round_robin_entry	*members;\n");
+	vsb_cat(sb, "};\n");
+	vsb_cat(sb, "\n");
+	vsb_cat(sb, "\n");
+	vsb_cat(sb, "/*\n");
 	vsb_cat(sb, " * other stuff.\n");
 	vsb_cat(sb, " * XXX: document when bored\n");
 	vsb_cat(sb, " */\n");
@@ -485,6 +500,7 @@
 	vsb_cat(sb, "/* Backend related */\n");
 	vsb_cat(sb, "void VRT_init_dir_simple(struct cli *, struct director **, const struct vrt_dir_simple *);\n");
 	vsb_cat(sb, "void VRT_init_dir_random(struct cli *, struct director **, const struct vrt_dir_random *);\n");
+	vsb_cat(sb, "void VRT_init_dir_round_robin(struct cli *, struct director **, const struct vrt_dir_round_robin *);\n");
 	vsb_cat(sb, "void VRT_fini_dir(struct cli *, struct director *);\n");
 	vsb_cat(sb, "\n");
 	vsb_cat(sb, "char *VRT_IP_string(const struct sess *sp, const struct sockaddr *sa);\n");




More information about the varnish-commit mailing list