[experimental-ims] 9cc19dd Introduce the "busyobj" structure which is only valid for busy objects.
Geoff Simmons
geoff at varnish-cache.org
Fri Jul 8 11:47:49 CEST 2011
commit 9cc19dd79740f6788cae2c4fed590e05523bb84b
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