r1894 - trunk/varnish-cache/bin/varnishd

phk at projects.linpro.no phk at projects.linpro.no
Mon Aug 20 14:19:16 CEST 2007


Author: phk
Date: 2007-08-20 14:19:16 +0200 (Mon, 20 Aug 2007)
New Revision: 1894

Modified:
   trunk/varnish-cache/bin/varnishd/cache.h
   trunk/varnish-cache/bin/varnishd/cache_backend.c
   trunk/varnish-cache/bin/varnishd/cache_vrt.c
Log:
Give backends a reference count and reuse any existing identical backend
when a new VCL instantiates a backend.

Drop backends when their reference count goes to zero.



Modified: trunk/varnish-cache/bin/varnishd/cache.h
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache.h	2007-08-20 12:18:15 UTC (rev 1893)
+++ trunk/varnish-cache/bin/varnishd/cache.h	2007-08-20 12:19:16 UTC (rev 1894)
@@ -347,12 +347,15 @@
 struct backend {
 	unsigned		magic;
 #define BACKEND_MAGIC		0x64c4c7c6
-	const char		*vcl_name;
+	char			*vcl_name;
 
+	TAILQ_ENTRY(backend)	list;
+	int			refcount;
+
 	struct backend_method	*method;
 
-	const char		*hostname;
-	const char		*portname;
+	char			*hostname;
+	char			*portname;
 
 	struct addrinfo		*addr;
 	struct addrinfo		*last_addr;
@@ -375,6 +378,12 @@
 
 };
 
+/*
+ * NB: This list is not locked, it is only ever manipulated from the
+ * cachers CLI thread.
+ */
+TAILQ_HEAD(backendlist, backend);
+
 /* Prototypes etc ----------------------------------------------------*/
 
 
@@ -393,6 +402,9 @@
 void VBE_RecycleFd(struct worker *w, struct vbe_conn *vc);
 struct bereq * VBE_new_bereq(void);
 void VBE_free_bereq(struct bereq *bereq);
+extern struct backendlist backendlist;
+void VBE_DropRef(struct backend *);
+struct backend *VBE_NewBackend(struct backend_method *method);
 
 /* cache_backend_simple.c */
 extern struct backend_method	backend_method_simple;

Modified: trunk/varnish-cache/bin/varnishd/cache_backend.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_backend.c	2007-08-20 12:18:15 UTC (rev 1893)
+++ trunk/varnish-cache/bin/varnishd/cache_backend.c	2007-08-20 12:19:16 UTC (rev 1894)
@@ -41,8 +41,10 @@
 
 static TAILQ_HEAD(,bereq) bereq_head = TAILQ_HEAD_INITIALIZER(bereq_head);
 
-static MTX vbemtx;
+static MTX VBE_mtx;
 
+struct backendlist backendlist = TAILQ_HEAD_INITIALIZER(backendlist);
+
 /*--------------------------------------------------------------------
  * Get a http structure for talking to the backend.
  */
@@ -53,11 +55,11 @@
 	struct bereq *bereq;
 	volatile unsigned len;
 
-	LOCK(&vbemtx);
+	LOCK(&VBE_mtx);
 	bereq = TAILQ_FIRST(&bereq_head);
 	if (bereq != NULL)
 		TAILQ_REMOVE(&bereq_head, bereq, list);
-	UNLOCK(&vbemtx);
+	UNLOCK(&VBE_mtx);
 	if (bereq != NULL) {
 		CHECK_OBJ(bereq, BEREQ_MAGIC);
 	} else {
@@ -81,13 +83,48 @@
 {
 
 	CHECK_OBJ_NOTNULL(bereq, BEREQ_MAGIC);
-	LOCK(&vbemtx);
+	LOCK(&VBE_mtx);
 	TAILQ_INSERT_HEAD(&bereq_head, bereq, list);
-	UNLOCK(&vbemtx);
+	UNLOCK(&VBE_mtx);
 }
 
 /*--------------------------------------------------------------------*/
 
+struct backend *
+VBE_NewBackend(struct backend_method *method)
+{
+	struct backend *b;
+
+	b = calloc(sizeof *b, 1);
+	XXXAN(b);
+	b->magic = BACKEND_MAGIC;
+	TAILQ_INIT(&b->connlist);
+	b->method = method;
+	b->refcount = 1;
+	TAILQ_INSERT_TAIL(&backendlist, b, list);
+	return (b);
+}
+
+/*--------------------------------------------------------------------*/
+
+void
+VBE_DropRef(struct backend *b)
+{
+
+	CHECK_OBJ_NOTNULL(b, BACKEND_MAGIC);
+
+	b->refcount--;
+	if (b->refcount > 0)
+		return;
+	TAILQ_REMOVE(&backendlist, b, list);
+	free(b->vcl_name);
+	free(b->portname);
+	free(b->hostname);
+	free(b);
+}
+
+/*--------------------------------------------------------------------*/
+
 struct vbe_conn *
 VBE_GetFd(struct sess *sp)
 {
@@ -119,6 +156,6 @@
 VBE_Init(void)
 {
 
-	MTX_INIT(&vbemtx);
+	MTX_INIT(&VBE_mtx);
 	backend_method_simple.init();
 }

Modified: trunk/varnish-cache/bin/varnishd/cache_vrt.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_vrt.c	2007-08-20 12:18:15 UTC (rev 1893)
+++ trunk/varnish-cache/bin/varnishd/cache_vrt.c	2007-08-20 12:19:16 UTC (rev 1894)
@@ -520,11 +520,27 @@
 {
 	struct backend *b;
 	
-	b = calloc(sizeof *b, 1);
-	XXXAN(b);
-	b->magic = BACKEND_MAGIC;
+	/*
+	 * Scan existing backends to see if we can recycle one of them.
+	 */
+	TAILQ_FOREACH(b, &backendlist, list) {
+		CHECK_OBJ_NOTNULL(b, BACKEND_MAGIC);
+		if (b->method != &backend_method_simple)
+			continue;
+		if (strcmp(b->vcl_name, t->name))
+			continue;
+		if (strcmp(b->portname, t->port))
+			continue;
+		if (strcmp(b->hostname, t->host))
+			continue;
+		b->refcount++;
+		*bp = b;
+		return;
+	}
+
+	b = VBE_NewBackend(&backend_method_simple);
+
 	b->dnsttl = 300;
-	TAILQ_INIT(&b->connlist);
 	b->last_check = TIM_mono();
 	b->minute_limit = 1;
 
@@ -540,13 +556,12 @@
 	b->hostname = strdup(t->host);
 	XXXAN(b->hostname);
 
-	b->method = &backend_method_simple;
-
 	*bp = b;
 }
 
 void
 VRT_fini_backend(struct backend *b)
 {
-	(void)b;
+
+	VBE_DropRef(b);	
 }




More information about the varnish-commit mailing list