[3.0] 35dc396 Introduce the "busyobj" structure which is only valid for busy objects.

Tollef Fog Heen tfheen at varnish-cache.org
Wed Aug 17 11:25:30 CEST 2011


commit 35dc396455141833cbfe7ed4b2a63a10e6687bfb
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Mon Jun 27 12:11:41 2011 +0000

    Introduce the "busyobj" structure which is only valid for busy objects.
    
    Use it to hold the derived vary string for the request (if any) and
    skip busy objects with non-matching Vary during hash lookup.
    
    Idea by:	sky

diff --git a/bin/varnishd/cache.h b/bin/varnishd/cache.h
index eb7077c..a875071 100644
--- a/bin/varnishd/cache.h
+++ b/bin/varnishd/cache.h
@@ -97,6 +97,7 @@ struct director;
 struct object;
 struct objhead;
 struct objcore;
+struct busyobj;
 struct storage;
 struct workreq;
 struct vrt_backend;
@@ -281,6 +282,7 @@ struct worker {
 	struct objhead		*nobjhead;
 	struct objcore		*nobjcore;
 	struct waitinglist	*nwaitinglist;
+	struct busyobj		*nbusyobj;
 	void			*nhashpriv;
 	struct dstat		stats;
 
@@ -416,6 +418,7 @@ struct objcore {
 	void			*priv;
 	unsigned		priv2;
 	struct objhead		*objhead;
+	struct busyobj		*busyobj;
 	double			timer_when;
 	unsigned		flags;
 #define OC_F_BUSY		(1<<1)
@@ -470,7 +473,16 @@ oc_getlru(const struct objcore *oc)
 	return (oc->methods->getlru(oc));
 }
 
+/* Busy Object structure ---------------------------------------------*/
+
+struct busyobj {
+	unsigned		magic;
+#define BUSYOBJ_MAGIC		0x23b95567
+	uint8_t			*vary;
+};
+
 /* Object structure --------------------------------------------------*/
+
 VTAILQ_HEAD(storagehead, storage);
 
 struct object {
diff --git a/bin/varnishd/cache_hash.c b/bin/varnishd/cache_hash.c
index d5c5ebe..6fdff15 100644
--- a/bin/varnishd/cache_hash.c
+++ b/bin/varnishd/cache_hash.c
@@ -111,6 +111,11 @@ HSH_Prealloc(const struct sess *sp)
 	}
 	CHECK_OBJ_NOTNULL(w->nwaitinglist, WAITINGLIST_MAGIC);
 
+	if (w->nbusyobj == NULL) {
+		ALLOC_OBJ(w->nbusyobj, BUSYOBJ_MAGIC);
+		XXXAN(w->nbusyobj);
+	}
+
 	if (hash->prep != NULL)
 		hash->prep(sp);
 }
@@ -342,8 +347,15 @@ HSH_Lookup(struct sess *sp, struct objhead **poh)
 		assert(oc->objhead == oh);
 
 		if (oc->flags & OC_F_BUSY) {
-			if (!sp->hash_ignore_busy)
-				busy_oc = oc;
+			CHECK_OBJ_NOTNULL(oc->busyobj, BUSYOBJ_MAGIC);
+			if (sp->hash_ignore_busy)
+				continue;
+
+			if (oc->busyobj->vary != NULL &&
+			    !VRY_Match(sp, oc->busyobj->vary))
+				continue;
+
+			busy_oc = oc;
 			continue;
 		}
 
@@ -445,6 +457,10 @@ HSH_Lookup(struct sess *sp, struct objhead **poh)
 	AN(oc->flags & OC_F_BUSY);
 	oc->refcnt = 1;
 
+	w->nbusyobj->vary = sp->vary_b;
+	oc->busyobj = w->nbusyobj;
+	w->nbusyobj = NULL;
+
 	/*
 	 * Busy objects go on the tail, so they will not trip up searches.
 	 * HSH_Unbusy() will move them to the front.
@@ -609,6 +625,9 @@ HSH_Unbusy(const struct sess *sp)
 	VTAILQ_REMOVE(&oh->objcs, oc, list);
 	VTAILQ_INSERT_HEAD(&oh->objcs, oc, list);
 	oc->flags &= ~OC_F_BUSY;
+	AZ(sp->wrk->nbusyobj);
+	sp->wrk->nbusyobj = oc->busyobj;
+	oc->busyobj = NULL;
 	hsh_rush(oh);
 	AN(oc->ban);
 	Lck_Unlock(&oh->mtx);
diff --git a/bin/varnishtest/tests/c00043.vtc b/bin/varnishtest/tests/c00043.vtc
new file mode 100644
index 0000000..46cc4e1
--- /dev/null
+++ b/bin/varnishtest/tests/c00043.vtc
@@ -0,0 +1,44 @@
+varnishtest "predictive vary"
+
+
+server s1 {
+	rxreq
+	txresp -hdr "Vary: foo" -bodylen 1
+	rxreq
+	sema r2 sync 2
+	sema r1 sync 2
+	txresp -hdr "Vary: foo" -bodylen 2
+} -start
+
+server s2 {
+	rxreq
+	txresp -hdr "Vary: foo" -bodylen 3
+} -start
+
+varnish v1 -vcl+backend {
+	sub vcl_recv {
+		if (req.http.bar) {
+			set req.backend = s2;
+		}
+	}
+} -start
+
+client c1 {
+	txreq -hdr "Foo: vary1"
+	rxresp
+	expect resp.bodylen == 1
+	txreq -hdr "Foo: vary2"
+	rxresp
+	expect resp.bodylen == 2
+} -start
+
+client c2 {
+	sema r2 sync 2
+	txreq -hdr "Foo: vary3" -hdr "bar: yes"
+	rxresp
+	sema r1 sync 2
+	expect resp.bodylen == 3
+} -start
+
+client c1 -wait
+client c2 -wait



More information about the varnish-commit mailing list