r2008 - trunk/varnish-cache/bin/varnishd

cecilihf at projects.linpro.no cecilihf at projects.linpro.no
Mon Sep 24 14:06:20 CEST 2007


Author: cecilihf
Date: 2007-09-24 14:06:20 +0200 (Mon, 24 Sep 2007)
New Revision: 2008

Modified:
   trunk/varnish-cache/bin/varnishd/cache_backend_random.c
   trunk/varnish-cache/bin/varnishd/cache_backend_round_robin.c
Log:
Update random and round-robin backends to use the new convenience functions.


Modified: trunk/varnish-cache/bin/varnishd/cache_backend_random.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_backend_random.c	2007-09-24 11:25:15 UTC (rev 2007)
+++ trunk/varnish-cache/bin/varnishd/cache_backend_random.c	2007-09-24 12:06:20 UTC (rev 2008)
@@ -39,7 +39,6 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
-#include <poll.h>
 
 #include "shmlog.h"
 #include "cache.h"
@@ -76,90 +75,74 @@
 	int			health;
 };
 
-/*--------------------------------------------------------------------*/
+/*--------------------------------------------------------------------
+ * Try to get a socket connected to one of the addresses on the list.
+ * We start from the cached "last good" address and try all items on
+ * the list exactly once.
+ * If a new DNS lookup is made while we try, we start over and try the
+ * new list exactly once.
+ */
 
 static int
 ber_conn_try_list(struct sess *sp, struct brspec *bs)
 {
 	struct addrinfo *ai, *from;
-	struct sockaddr_storage ss;
-	int fam, sockt, proto;
-	socklen_t alen;
 	int s, loops;
-	char abuf1[TCP_ADDRBUFSIZE], abuf2[TCP_ADDRBUFSIZE];
-	char pbuf1[TCP_PORTBUFSIZE], pbuf2[TCP_PORTBUFSIZE];
 	unsigned myseq;
 
+	CHECK_OBJ_NOTNULL(bs, BRSPEC_MAGIC);
+	if (bs->addr == NULL)
+		return (-1);
+	AN(bs->last_addr);
+
 	/* Called with lock held */
 	myseq = bs->dnsseq;
 	loops = 0;
-	from = bs->last_addr;
-	for (ai = from; ai != NULL && (loops != 1 || ai != from);) {
-		fam = ai->ai_family;
-		sockt = ai->ai_socktype;
-		proto = ai->ai_protocol;
-		alen = ai->ai_addrlen;
-		assert(alen <= sizeof ss);
-		memcpy(&ss, ai->ai_addr, alen);
-		UNLOCK(&sp->backend->mtx);
-		s = socket(fam, sockt, proto);
-		if (s >= 0 && connect(s, (void *)&ss, alen)) {
-			AZ(close(s));
-			s = -1;
-		}
-		if (s >= 0) {
-			TCP_myname(s, abuf1, sizeof abuf1, pbuf1, sizeof pbuf1);
-			TCP_name((void*)&ss, alen,
-			    abuf2, sizeof abuf2, pbuf2, sizeof pbuf2);
-			WSL(sp->wrk, SLT_BackendOpen, s, "%s %s %s %s %s",
-			    sp->backend->vcl_name, abuf1, pbuf1, abuf2, pbuf2);
-		}
-		LOCK(&sp->backend->mtx);
-		if (s >= 0) {
+	ai = from = bs->last_addr;
+	while (1) {
+
+		/* NB: releases/acquires lock */
+		s = VBE_TryConnect(sp, ai);
+
+		if (s >= 0) { 
+			/* Update cached "last good" if still valid */
 			if (myseq == bs->dnsseq)
 				bs->last_addr = ai;
 			return (s);
 		}
+
 		if (myseq != bs->dnsseq) {
+			/* A DNS-lookup happended, try again from start */
 			loops = 0;
 			from = bs->last_addr;
 			ai = from;
 		} else {
+			/* Try next one */
 			ai = ai->ai_next;
 			if (ai == NULL) {
 				loops++;
 				ai = bs->addr;
 			}
 		}
+		if (loops == 1 && ai == from)
+			return (-1);
 	}
-	return (-1);
 }
 
 /*--------------------------------------------------------------------*/
 
-static int
-ber_conn_try(struct sess *sp, struct backend *bp, struct brspec *bs)
+static const char *
+ber_dns_lookup(struct backend *bp, struct brspec *bs)
 {
-	int s;
 	struct addrinfo *res, hint, *old;
 	int error;
 
-	LOCK(&bp->mtx);
+	CHECK_OBJ_NOTNULL(bp, BACKEND_MAGIC);
+	CHECK_OBJ_NOTNULL(bs, BRSPEC_MAGIC);
 
-	s = ber_conn_try_list(sp, bs);
-	if (s >= 0) {
-		bp->refcount++;
-		UNLOCK(&bp->mtx);
-		return (s);
-	}
-
-	if (bs->dnstime + bs->dnsttl >= TIM_mono()) {
-		UNLOCK(&bp->mtx);
-		return (-1);
-	}
-
-	/* Then do another lookup to catch DNS changes */
 	bs->dnstime = TIM_mono();
+
+	/* Let go of lock while we do sleepable stuff */
 	UNLOCK(&bp->mtx);
 
 	memset(&hint, 0, sizeof hint);
@@ -169,21 +152,44 @@
 	error = getaddrinfo(bs->hostname,
 	    bs->portname == NULL ? "http" : bs->portname,
 	    &hint, &res);
+	LOCK(&bp->mtx);
 	if (error) {
 		if (res != NULL)
 			freeaddrinfo(res);
-		printf("getaddrinfo: %s\n", gai_strerror(error)); /* XXX */
-		LOCK(&bp->mtx);
-	} else {
-		LOCK(&bp->mtx);
-		bs->dnsseq++;
-		old = bs->addr;
-		bs->last_addr = res;
-		bs->addr = res;
-		if (old != NULL)
-			freeaddrinfo(old);
+		return(gai_strerror(error));
+	} 
+	bs->dnsseq++;
+	old = bs->addr;
+	bs->last_addr = res;
+	bs->addr = res;
+	if (old != NULL)
+		freeaddrinfo(old);
+	return (NULL);
+}
+
+/*--------------------------------------------------------------------*/
+
+static int
+ber_conn_try(struct sess *sp, struct backend *bp, struct brspec *bs)
+{
+	int s;
+
+	LOCK(&bp->mtx);
+
+	s = ber_conn_try_list(sp, bs);
+	if (s >= 0) {
+		bp->refcount++;
+		UNLOCK(&bp->mtx);
+		return (s);
 	}
 
+	if (bs->dnstime + bs->dnsttl >= TIM_mono()) {
+		UNLOCK(&bp->mtx);
+		return (-1);
+	}
+
+	(void)ber_dns_lookup(bp, bs);
+
 	/* And try the entire list */
 	s = ber_conn_try_list(sp, bs);
 	if (s >= 0) {
@@ -194,6 +200,7 @@
 
 	UNLOCK(&bp->mtx);
 	return (-1);
+
 }
 
 
@@ -213,14 +220,13 @@
 ber_nextfd(struct sess *sp)
 {
 	struct vbe_conn *vc;
-	struct pollfd pfd;
 	struct backend *bp;
 	int reuse = 0;
 	struct ber *ber;
 	struct brspec *bs;
-	double r;
 	int min_health = -10;
 	int num = 0;
+	double r = 0;
 
 	CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
 	CHECK_OBJ_NOTNULL(sp->backend, BACKEND_MAGIC);
@@ -245,8 +251,8 @@
 			min_health *= 10;
 			num = 0;
 		}
-	}	
-
+	}
+		
 	while (1) {
 		LOCK(&bp->mtx);
 		vc = TAILQ_FIRST(&bs->connlist);
@@ -255,17 +261,12 @@
 			assert(vc->backend == bp);
 			assert(vc->fd >= 0);
 			TAILQ_REMOVE(&bs->connlist, vc, list);
-			vc->priv = bs;
 		}
 		UNLOCK(&bp->mtx);
 		if (vc == NULL)
 			break;
 
-		/* Test the connection for remote close before we use it */
-		pfd.fd = vc->fd;
-		pfd.events = POLLIN;
-		pfd.revents = 0;
-		if (!poll(&pfd, 1, 0)) {
+		if (VBE_CheckFd(vc->fd)) {
 			/* XXX locking of stats */
 			VSL_stats->backend_reuse += reuse;
 			VSL_stats->backend_conn++;
@@ -287,6 +288,7 @@
 	vc->priv = bs;
 	VSL_stats->backend_conn++;
 	return (vc);
+	
 }
 
 static struct vbe_conn *
@@ -419,14 +421,6 @@
 
 /*--------------------------------------------------------------------*/
 
-static void
-ber_Init(void)
-{
-
-}
-
-/*--------------------------------------------------------------------*/
-
 struct backend_method backend_method_random = {
 	.name =			"random",
 	.getfd =		ber_GetFd,
@@ -435,7 +429,6 @@
 	.gethostname =		ber_GetHostname,
 	.updatehealth =		ber_UpdateHealth,
 	.cleanup =		ber_Cleanup,
-	.init =			ber_Init
 };
 
 /*--------------------------------------------------------------------*/

Modified: trunk/varnish-cache/bin/varnishd/cache_backend_round_robin.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_backend_round_robin.c	2007-09-24 11:25:15 UTC (rev 2007)
+++ trunk/varnish-cache/bin/varnishd/cache_backend_round_robin.c	2007-09-24 12:06:20 UTC (rev 2008)
@@ -39,7 +39,6 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
-#include <poll.h>
 
 #include "shmlog.h"
 #include "cache.h"
@@ -75,90 +74,74 @@
 	int			health;
 };
 
-/*--------------------------------------------------------------------*/
+/*--------------------------------------------------------------------
+ * Try to get a socket connected to one of the addresses on the list.
+ * We start from the cached "last good" address and try all items on
+ * the list exactly once.
+ * If a new DNS lookup is made while we try, we start over and try the
+ * new list exactly once.
+ */
 
 static int
 brr_conn_try_list(struct sess *sp, struct bspec *bs)
 {
 	struct addrinfo *ai, *from;
-	struct sockaddr_storage ss;
-	int fam, sockt, proto;
-	socklen_t alen;
 	int s, loops;
-	char abuf1[TCP_ADDRBUFSIZE], abuf2[TCP_ADDRBUFSIZE];
-	char pbuf1[TCP_PORTBUFSIZE], pbuf2[TCP_PORTBUFSIZE];
 	unsigned myseq;
 
+	CHECK_OBJ_NOTNULL(bs, BSPEC_MAGIC);
+	if (bs->addr == NULL)
+		return (-1);
+	AN(bs->last_addr);
+
 	/* Called with lock held */
 	myseq = bs->dnsseq;
 	loops = 0;
-	from = bs->last_addr;
-	for (ai = from; ai != NULL && (loops != 1 || ai != from);) {
-		fam = ai->ai_family;
-		sockt = ai->ai_socktype;
-		proto = ai->ai_protocol;
-		alen = ai->ai_addrlen;
-		assert(alen <= sizeof ss);
-		memcpy(&ss, ai->ai_addr, alen);
-		UNLOCK(&sp->backend->mtx);
-		s = socket(fam, sockt, proto);
-		if (s >= 0 && connect(s, (void *)&ss, alen)) {
-			AZ(close(s));
-			s = -1;
-		}
-		if (s >= 0) {
-			TCP_myname(s, abuf1, sizeof abuf1, pbuf1, sizeof pbuf1);
-			TCP_name((void*)&ss, alen,
-			    abuf2, sizeof abuf2, pbuf2, sizeof pbuf2);
-			WSL(sp->wrk, SLT_BackendOpen, s, "%s %s %s %s %s",
-			    sp->backend->vcl_name, abuf1, pbuf1, abuf2, pbuf2);
-		}
-		LOCK(&sp->backend->mtx);
-		if (s >= 0) {
+	ai = from = bs->last_addr;
+	while (1) {
+
+		/* NB: releases/acquires lock */
+		s = VBE_TryConnect(sp, ai);
+
+		if (s >= 0) { 
+			/* Update cached "last good" if still valid */
 			if (myseq == bs->dnsseq)
 				bs->last_addr = ai;
 			return (s);
 		}
+
 		if (myseq != bs->dnsseq) {
+			/* A DNS-lookup happended, try again from start */
 			loops = 0;
 			from = bs->last_addr;
 			ai = from;
 		} else {
+			/* Try next one */
 			ai = ai->ai_next;
 			if (ai == NULL) {
 				loops++;
 				ai = bs->addr;
 			}
 		}
+		if (loops == 1 && ai == from)
+			return (-1);
 	}
-	return (-1);
 }
 
 /*--------------------------------------------------------------------*/
 
-static int
-brr_conn_try(struct sess *sp, struct backend *bp, struct bspec *bs)
+static const char *
+brr_dns_lookup(struct backend *bp, struct bspec *bs)
 {
-	int s;
 	struct addrinfo *res, hint, *old;
 	int error;
 
-	LOCK(&bp->mtx);
+	CHECK_OBJ_NOTNULL(bp, BACKEND_MAGIC);
+	CHECK_OBJ_NOTNULL(bs, BSPEC_MAGIC);
 
-	s = brr_conn_try_list(sp, bs);
-	if (s >= 0) {
-		bp->refcount++;
-		UNLOCK(&bp->mtx);
-		return (s);
-	}
-
-	if (bs->dnstime + bs->dnsttl >= TIM_mono()) {
-		UNLOCK(&bp->mtx);
-		return (-1);
-	}
-
-	/* Then do another lookup to catch DNS changes */
 	bs->dnstime = TIM_mono();
+
+	/* Let go of lock while we do sleepable stuff */
 	UNLOCK(&bp->mtx);
 
 	memset(&hint, 0, sizeof hint);
@@ -168,21 +151,44 @@
 	error = getaddrinfo(bs->hostname,
 	    bs->portname == NULL ? "http" : bs->portname,
 	    &hint, &res);
+	LOCK(&bp->mtx);
 	if (error) {
 		if (res != NULL)
 			freeaddrinfo(res);
-		printf("getaddrinfo: %s\n", gai_strerror(error)); /* XXX */
-		LOCK(&bp->mtx);
-	} else {
-		LOCK(&bp->mtx);
-		bs->dnsseq++;
-		old = bs->addr;
-		bs->last_addr = res;
-		bs->addr = res;
-		if (old != NULL)
-			freeaddrinfo(old);
+		return(gai_strerror(error));
+	} 
+	bs->dnsseq++;
+	old = bs->addr;
+	bs->last_addr = res;
+	bs->addr = res;
+	if (old != NULL)
+		freeaddrinfo(old);
+	return (NULL);
+}
+
+/*--------------------------------------------------------------------*/
+
+static int
+brr_conn_try(struct sess *sp, struct backend *bp, struct bspec *bs)
+{
+	int s;
+
+	LOCK(&bp->mtx);
+
+	s = brr_conn_try_list(sp, bs);
+	if (s >= 0) {
+		bp->refcount++;
+		UNLOCK(&bp->mtx);
+		return (s);
 	}
 
+	if (bs->dnstime + bs->dnsttl >= TIM_mono()) {
+		UNLOCK(&bp->mtx);
+		return (-1);
+	}
+
+	(void)brr_dns_lookup(bp, bs);
+
 	/* And try the entire list */
 	s = brr_conn_try_list(sp, bs);
 	if (s >= 0) {
@@ -212,7 +218,6 @@
 brr_nextfd(struct sess *sp)
 {
 	struct vbe_conn *vc;
-	struct pollfd pfd;
 	struct backend *bp;
 	int reuse = 0;
 	struct brr *brr;
@@ -233,7 +238,7 @@
 			num = 0;
 		}
 	} while (bs->health < min_health);
-	
+		
 	while (1) {
 		LOCK(&bp->mtx);
 		vc = TAILQ_FIRST(&bs->connlist);
@@ -242,17 +247,12 @@
 			assert(vc->backend == bp);
 			assert(vc->fd >= 0);
 			TAILQ_REMOVE(&bs->connlist, vc, list);
-			vc->priv = bs;
 		}
 		UNLOCK(&bp->mtx);
 		if (vc == NULL)
 			break;
 
-		/* Test the connection for remote close before we use it */
-		pfd.fd = vc->fd;
-		pfd.events = POLLIN;
-		pfd.revents = 0;
-		if (!poll(&pfd, 1, 0)) {
+		if (VBE_CheckFd(vc->fd)) {
 			/* XXX locking of stats */
 			VSL_stats->backend_reuse += reuse;
 			VSL_stats->backend_conn++;
@@ -407,14 +407,6 @@
 
 /*--------------------------------------------------------------------*/
 
-static void
-brr_Init(void)
-{
-
-}
-
-/*--------------------------------------------------------------------*/
-
 struct backend_method backend_method_round_robin = {
 	.name =			"round_robin",
 	.getfd =		brr_GetFd,
@@ -423,7 +415,6 @@
 	.gethostname =		brr_GetHostname,
 	.updatehealth =		brr_UpdateHealth,
 	.cleanup =		brr_Cleanup,
-	.init =			brr_Init
 };
 
 /*--------------------------------------------------------------------*/




More information about the varnish-commit mailing list