r2344 - trunk/varnish-cache/bin/varnishd

phk at projects.linpro.no phk at projects.linpro.no
Mon Jan 14 11:42:58 CET 2008


Author: phk
Date: 2008-01-14 11:42:56 +0100 (Mon, 14 Jan 2008)
New Revision: 2344

Modified:
   trunk/varnish-cache/bin/varnishd/cache.h
   trunk/varnish-cache/bin/varnishd/cache_expire.c
   trunk/varnish-cache/bin/varnishd/cache_hash.c
   trunk/varnish-cache/bin/varnishd/cache_vrt.c
   trunk/varnish-cache/bin/varnishd/mgt_vcc.c
Log:

Pave more road for prefetch:

Sanity-check values assigned to obj.prefetch from VCL: if before present
time or after ttl, SHM a VCL_info message and set obj.prefetch to zero
disabling prefetch.

Change objects/timer interaction:  We only keep track of the first timer for
each object (->timer_when) and add a field to remember what we intend to
do at that time (->timer_what).

Rename heap_idx to timer_idx to group the relevant fields (XXX: it should be
accessed through function outside cache_expire.c which should be called
cache_timer.c now).

Abolish the 30 second advance move to death-row.

When the prefetch timer expires, SHM a debug message and don't do anything.

Minor polishing and cleanup.

Add vcl_prefetch{} to default VCL and set prefetch 30 seconds before ttl.


Modified: trunk/varnish-cache/bin/varnishd/cache.h
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache.h	2008-01-14 10:30:47 UTC (rev 2343)
+++ trunk/varnish-cache/bin/varnishd/cache.h	2008-01-14 10:42:56 UTC (rev 2344)
@@ -232,7 +232,13 @@
 	struct ws		ws_o[1];
 	unsigned char		*vary;
 
-	unsigned		heap_idx;
+	double			timer_when;
+	enum {
+	    TIMER_TTL,
+	    TIMER_PREFETCH
+	}			timer_what;
+	unsigned		timer_idx;
+
 	unsigned		ban_seq;
 
 	unsigned		pass;

Modified: trunk/varnish-cache/bin/varnishd/cache_expire.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_expire.c	2008-01-14 10:30:47 UTC (rev 2343)
+++ trunk/varnish-cache/bin/varnishd/cache_expire.c	2008-01-14 10:42:56 UTC (rev 2344)
@@ -50,7 +50,6 @@
 static pthread_t exp_thread;
 static struct binheap *exp_heap;
 static MTX exp_mtx;
-static unsigned expearly = 30;
 static VTAILQ_HEAD(,object) exp_deathrow = VTAILQ_HEAD_INITIALIZER(exp_deathrow);
 static VTAILQ_HEAD(,object) exp_lru = VTAILQ_HEAD_INITIALIZER(exp_lru);
 
@@ -61,6 +60,30 @@
  */
 static const unsigned lru_target = (unsigned)(-3);
 
+/*--------------------------------------------------------------------
+ * Figure out which object timer fires next
+ */
+
+/* When does the timer fire for this object ? */
+static void
+update_object_when(struct object *o)
+{
+	double w;
+
+	w = o->ttl;
+	if (o->prefetch < 0.0) {
+		o->timer_when = o->ttl + o->prefetch;
+		o->timer_what = TIMER_PREFETCH;
+	} else if (o->prefetch > 0.0) {
+		assert(o->prefetch <= o->ttl);
+		o->timer_when = o->prefetch;
+		o->timer_what = TIMER_PREFETCH;
+	} else {
+		o->timer_when = o->ttl;
+		o->timer_what = TIMER_TTL;
+	}
+}
+
 /*--------------------------------------------------------------------*/
 
 void
@@ -68,7 +91,8 @@
 {
 
 	CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC);
-	assert(o->heap_idx == 0);
+	assert(o->timer_idx == 0);
+	update_object_when(o);
 	LOCK(&exp_mtx);
 	binheap_insert(exp_heap, o);
 	VTAILQ_INSERT_TAIL(&exp_lru, o, deathrow);
@@ -82,7 +106,7 @@
 	CHECK_OBJ_NOTNULL(o, OBJECT_MAGIC);
 	if (o->lru_stamp + params->lru_timeout < now) {
 		LOCK(&exp_mtx);	/* XXX: should be ..._TRY */
-		if (o->heap_idx != lru_target && o->heap_idx != 0) {
+		if (o->timer_idx != lru_target && o->timer_idx != 0) {
 			VTAILQ_REMOVE(&exp_lru, o, deathrow);
 			VTAILQ_INSERT_TAIL(&exp_lru, o, deathrow);
 			o->lru_stamp = now;
@@ -96,9 +120,10 @@
 {
 
 	LOCK(&exp_mtx);
-	if (o->heap_idx != lru_target) {
-		assert(o->heap_idx != 0);
-		binheap_delete(exp_heap, o->heap_idx);
+	if (o->timer_idx != lru_target) {
+		assert(o->timer_idx != 0);	/* XXX: symbolic zero ? */
+		update_object_when(o);
+		binheap_delete(exp_heap, o->timer_idx);
 		binheap_insert(exp_heap, o);
 	}
 	UNLOCK(&exp_mtx);
@@ -185,40 +210,58 @@
 		LOCK(&exp_mtx);
 		o = binheap_root(exp_heap);
 		CHECK_OBJ_ORNULL(o, OBJECT_MAGIC);
-		if (o == NULL || o->ttl > t + expearly) {
+		if (o == NULL || o->timer_when > t) {	/* XXX: >= ? */
 			UNLOCK(&exp_mtx);
+			WSL_Flush(&ww);
 			AZ(sleep(1));
 			VCL_Refresh(&sp->vcl);
 			t = TIM_real();
 			continue;
 		}
-		binheap_delete(exp_heap, o->heap_idx);
-		assert(o->heap_idx == 0);
+		binheap_delete(exp_heap, o->timer_idx);
+		assert(o->timer_idx == 0);
 
 		/* Sanity check */
 		o2 = binheap_root(exp_heap);
 		if (o2 != NULL)
-			assert(o2->ttl >= o->ttl);
+			assert(o2->timer_when >= o->timer_when);
 
 		UNLOCK(&exp_mtx);
-		WSL(&ww, SLT_ExpPick, 0, "%u", o->xid);
 
-		sp->obj = o;
-		VCL_timeout_method(sp);
+		WSL(&ww, SLT_ExpPick, 0, "%u %s", o->xid,
+		    o->timer_what == TIMER_PREFETCH ? "prefetch" : "ttl");
 
-		if (sp->handling == VCL_RET_DISCARD) {
+		if (o->timer_what == TIMER_PREFETCH) {
+			o->prefetch = 0.0;
+			update_object_when(o);
 			LOCK(&exp_mtx);
-			VTAILQ_REMOVE(&exp_lru, o, deathrow);
-			VTAILQ_INSERT_TAIL(&exp_deathrow, o, deathrow);
-			VSL_stats->n_deathrow++;
+			binheap_insert(exp_heap, o);
 			UNLOCK(&exp_mtx);
-			continue;
+			sp->obj = o;
+			VCL_prefetch_method(sp);
+			if (sp->handling == VCL_RET_FETCH) {
+				WSL(&ww, SLT_Debug, 0, "Attempt Prefetch %u",
+				    o->xid);
+			}
+		} else { /* TIMER_TTL */
+			sp->obj = o;
+			VCL_timeout_method(sp);
+
+			if (sp->handling == VCL_RET_DISCARD) {
+				LOCK(&exp_mtx);
+				VTAILQ_REMOVE(&exp_lru, o, deathrow);
+				VTAILQ_INSERT_TAIL(&exp_deathrow, o, deathrow);
+				VSL_stats->n_deathrow++;
+				UNLOCK(&exp_mtx);
+			}
+			assert(sp->handling == VCL_RET_DISCARD);
 		}
-		assert(sp->handling == VCL_RET_DISCARD);
 	}
 }
 
-/*--------------------------------------------------------------------*/
+/*--------------------------------------------------------------------
+ * BinHeap helper functions for objects.
+ */
 
 static int
 object_cmp(void *priv, void *a, void *b)
@@ -226,19 +269,19 @@
 	struct object *aa, *bb;
 
 	(void)priv;
-
-	aa = a;
-	bb = b;
-	return (aa->ttl < bb->ttl);
+	CAST_OBJ_NOTNULL(aa, a, OBJECT_MAGIC);
+	CAST_OBJ_NOTNULL(bb, b, OBJECT_MAGIC);
+	return (aa->timer_when < bb->timer_when);
 }
 
 static void
 object_update(void *priv, void *p, unsigned u)
 {
-	struct object *o = p;
+	struct object *o;
 
 	(void)priv;
-	o->heap_idx = u;
+	CAST_OBJ_NOTNULL(o, p, OBJECT_MAGIC);
+	o->timer_idx = u;
 }
 
 /*--------------------------------------------------------------------
@@ -263,9 +306,9 @@
 		 * means that we own the EXP refcnt on this object.
 		 */
 		VTAILQ_REMOVE(&exp_lru, o, deathrow);
-		binheap_delete(exp_heap, o->heap_idx);
-		assert(o->heap_idx == 0);
-		o->heap_idx = lru_target;
+		binheap_delete(exp_heap, o->timer_idx);
+		assert(o->timer_idx == 0);
+		o->timer_idx = lru_target;
 		VSL_stats->n_lru_nuked++; 	/* May be premature */
 	}
 	UNLOCK(&exp_mtx);
@@ -296,7 +339,7 @@
 	LOCK(&exp_mtx);
 	VSL_stats->n_lru_nuked--; 		/* It was premature */
 	VSL_stats->n_lru_saved++;
-	o->heap_idx = 0;
+	o->timer_idx = 0;
 	o->lru_stamp = sp->wrk->used;
 	binheap_insert(exp_heap, o);
 	VTAILQ_INSERT_TAIL(&exp_lru, o, deathrow);

Modified: trunk/varnish-cache/bin/varnishd/cache_hash.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_hash.c	2008-01-14 10:30:47 UTC (rev 2343)
+++ trunk/varnish-cache/bin/varnishd/cache_hash.c	2008-01-14 10:42:56 UTC (rev 2344)
@@ -216,7 +216,7 @@
 		    h->hd[HTTP_HDR_URL].b, oh->hash)) {
 			o->ttl = 0;
 			WSP(sp, SLT_ExpBan, "%u was banned", o->xid);
-			if (o->heap_idx != 0)
+			if (o->timer_idx != 0)
 				EXP_TTLchange(o);
 		} else if (o->vary == NULL || VRY_Match(sp, o->vary))
 			break;

Modified: trunk/varnish-cache/bin/varnishd/cache_vrt.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_vrt.c	2008-01-14 10:30:47 UTC (rev 2343)
+++ trunk/varnish-cache/bin/varnishd/cache_vrt.c	2008-01-14 10:42:56 UTC (rev 2344)
@@ -292,7 +292,7 @@
 	if (a < 0)
 		a = 0;
 	sp->obj->ttl = sp->t_req + a;
-	if (sp->obj->heap_idx != 0)
+	if (sp->obj->timer_idx != 0)
 		EXP_TTLchange(sp->obj);
 }
 
@@ -306,15 +306,31 @@
 
 /*--------------------------------------------------------------------*/
 
+/* XXX: the VCL_info messages has unexpected fractions on the ttl */
+
 void
 VRT_l_obj_prefetch(const struct sess *sp, double a)
 {
 
 	CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);
 	CHECK_OBJ_NOTNULL(sp->obj, OBJECT_MAGIC);	/* XXX */
-	sp->obj->prefetch = a;
-	if (a > 0.0)
-		sp->obj->prefetch += sp->t_req;
+	sp->obj->prefetch = 0.0;
+	if (a == 0.0)
+		sp->obj->prefetch = a;
+	else if (a > 0.0 && a + sp->t_req <= sp->obj->ttl)
+		sp->obj->prefetch = a + sp->t_req;
+	else if (a < 0.0 && a + sp->obj->ttl > sp->t_req)
+		sp->obj->prefetch = a;
+	else if (a > 0.0)
+		WSL(sp->wrk, SLT_VCL_info, sp->id,
+		    "XID %u: obj.prefetch (%g) after TTL (%g), ignored.",
+		    sp->obj->xid, a, sp->obj->ttl - sp->t_req);
+	else /* if (a < 0.0) */
+		WSL(sp->wrk, SLT_VCL_info, sp->id,
+		    "XID %u: obj.prefetch (%g) less than ttl (%g), ignored.",
+		    sp->obj->xid, a, sp->obj->ttl - sp->t_req);
+	if (sp->obj->timer_idx != 0)
+		EXP_TTLchange(sp->obj);
 }
 
 double

Modified: trunk/varnish-cache/bin/varnishd/mgt_vcc.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/mgt_vcc.c	2008-01-14 10:30:47 UTC (rev 2343)
+++ trunk/varnish-cache/bin/varnishd/mgt_vcc.c	2008-01-14 10:42:56 UTC (rev 2344)
@@ -128,6 +128,7 @@
     "    if (obj.http.Set-Cookie) {\n"
     "        pass;\n"
     "    }\n"
+    "	 set obj.prefetch =  -30s;"
     "    insert;\n"
     "}\n"
     "sub vcl_deliver {\n"
@@ -136,6 +137,9 @@
     "sub vcl_discard {\n"
     "    discard;\n"
     "}\n"
+    "sub vcl_prefetch {\n"
+    "    fetch;\n"
+    "}\n"
     "sub vcl_timeout {\n"
     "    discard;\n"
     "}\n";
@@ -278,7 +282,7 @@
 	/* Next, try to load the object into the management process */
 	if ((dlh = dlopen(of, RTLD_NOW | RTLD_LOCAL)) == NULL) {
 		vsb_printf(sb,
-		    "%s(): failed to load compiled VCL program: %s",
+		    "%s(): failed to load compiled VCL program:\n  %s",
 		    __func__, dlerror());
 		unlink(of);
 		free(of);
@@ -419,7 +423,7 @@
 	if (C_flag)
 		return (0);
 	if (vf == NULL) {
-		fprintf(stderr, "VCL compilation failed");
+		fprintf(stderr, "\nVCL compilation failed\n");
 		return (1);
 	}
 	vp = mgt_vcc_add("boot", vf);




More information about the varnish-commit mailing list