[experimental-ims] c1a6faa Move 'age' and 'entered' into struct exp.

Geoff Simmons geoff at varnish-cache.org
Wed Aug 31 16:00:19 CEST 2011


commit c1a6faaf55ac0d5c4fee8bbc0b9281f5c1118592
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Wed Aug 10 07:52:02 2011 +0000

    Move 'age' and 'entered' into struct exp.
    
    Simplify the move from sp->wrk to sp->obj accordingly.
    
    Add a diagram that explains how ttl, grace & keep related to
    each other.
    
    Fix VCL's obj.ttl variable to appear to be relative to "now" rather
    than obj->entered. (#956)
    
    Also log SLT_TTL when we change obj.grace and obj.keep
    
    Make SLT_TTL always have the same format:
    	XID
    	"RFC" or "VCL"
    	obj.ttl
    	obj.grace
    	obj.keep
    	obj.entered
    	obj.age
    In addition "RFC" has:
    	obj.date
    	obj.expires
    	obj.max-age
    
    Fixes	#956
    
    Thanks to:	DocWilco

diff --git a/bin/varnishd/cache.h b/bin/varnishd/cache.h
index a875071..2d04724 100644
--- a/bin/varnishd/cache.h
+++ b/bin/varnishd/cache.h
@@ -242,6 +242,8 @@ struct exp {
 	double			ttl;
 	double			grace;
 	double			keep;
+	double			age;
+	double			entered;
 };
 
 /*--------------------------------------------------------------------*/
@@ -309,8 +311,6 @@ struct worker {
 	struct http		*beresp;
 	struct http		*resp;
 
-	double			age;
-	double			entered;
 	struct exp		exp;
 
 	/* This is only here so VRT can find it */
@@ -507,8 +507,6 @@ struct object {
 
 	ssize_t			len;
 
-	double			age;
-	double			entered;
 	struct exp		exp;
 
 	double			last_modified;
diff --git a/bin/varnishd/cache_center.c b/bin/varnishd/cache_center.c
index f93a61b..beb3d55 100644
--- a/bin/varnishd/cache_center.c
+++ b/bin/varnishd/cache_center.c
@@ -428,7 +428,7 @@ cnt_error(struct sess *sp)
 		}
 		AN(sp->obj);
 		sp->obj->xid = sp->xid;
-		sp->obj->entered = sp->t_req;
+		sp->obj->exp.entered = sp->t_req;
 	} else {
 		/* XXX: Null the headers ? */
 	}
@@ -554,9 +554,8 @@ cnt_fetch(struct sess *sp)
 		/*
 		 * What does RFC2616 think about TTL ?
 		 */
-		sp->wrk->entered = TIM_real();
-		sp->wrk->age = 0;
 		EXP_Clr(&sp->wrk->exp);
+		sp->wrk->exp.entered = TIM_real();
 		sp->wrk->exp.ttl = RFC2616_Ttl(sp);
 
 		/* pass from vclrecv{} has negative TTL */
@@ -782,8 +781,6 @@ cnt_fetchbody(struct sess *sp)
 
 	sp->obj->xid = sp->xid;
 	sp->obj->response = sp->err_code;
-	sp->obj->age = sp->wrk->age;
-	sp->obj->entered = sp->wrk->entered;
 	WS_Assert(sp->obj->ws_o);
 
 	/* Filter into object */
@@ -799,7 +796,7 @@ cnt_fetchbody(struct sess *sp)
 	if (http_GetHdr(hp, H_Last_Modified, &b))
 		sp->obj->last_modified = TIM_parse(b);
 	else
-		sp->obj->last_modified = floor(sp->wrk->entered);
+		sp->obj->last_modified = floor(sp->wrk->exp.entered);
 
 	assert(WRW_IsReleased(sp->wrk));
 
diff --git a/bin/varnishd/cache_expire.c b/bin/varnishd/cache_expire.c
index c0e79cc..7822bf6 100644
--- a/bin/varnishd/cache_expire.c
+++ b/bin/varnishd/cache_expire.c
@@ -35,6 +35,18 @@
  *
  * We hold a single object reference for both data structures.
  *
+ * An attempted overview:
+ *
+ *	                        EXP_Ttl()      EXP_Grace()   EXP_Keep()
+ *				   |                |            |
+ *      entered                    v                v            |
+ *         |                       +--------------->+            |
+ *         v                       |      grace                  |
+ *         +---------------------->+                             |
+ *                  ttl            |                             v
+ *                                 +---------------------------->+
+ *                                     keep
+ *				   
  */
 
 #include "config.h"
@@ -68,6 +80,8 @@ EXP_Clr(struct exp *e)
 	e->ttl = -1;
 	e->grace = -1;
 	e->keep = -1;
+	e->age = 0;
+	e->entered = 0;
 }
 
 #define EXP_ACCESS(fld, low_val, extra)				\
@@ -93,8 +107,8 @@ EXP_ACCESS(grace, 0., )
 EXP_ACCESS(keep, 0.,)
 
 /*--------------------------------------------------------------------
- * Calculate when an object is out of ttl or grace, possibly constrained
- * by per-session limits.
+ * Calculate an objects effective keep, grace or ttl time, suitably
+ * adjusted for defaults and by per-session limits.
  */
 
 static double
@@ -131,7 +145,7 @@ EXP_Ttl(const struct sess *sp, const struct object *o)
 	r = o->exp.ttl;
 	if (sp != NULL && sp->exp.ttl > 0. && sp->exp.ttl < r)
 		r = sp->exp.ttl;
-	return (o->entered + r);
+	return (o->exp.entered + r);
 }
 
 /*--------------------------------------------------------------------
@@ -214,8 +228,8 @@ EXP_Insert(struct object *o)
 	AssertObjBusy(o);
 	HSH_Ref(oc);
 
-	assert(o->entered != 0 && !isnan(o->entered));
-	o->last_lru = o->entered;
+	assert(o->exp.entered != 0 && !isnan(o->exp.entered));
+	o->last_lru = o->exp.entered;
 
 	lru = oc_getlru(oc);
 	CHECK_OBJ_NOTNULL(lru, LRU_MAGIC);
diff --git a/bin/varnishd/cache_hash.c b/bin/varnishd/cache_hash.c
index 0ca8766..739fee0 100644
--- a/bin/varnishd/cache_hash.c
+++ b/bin/varnishd/cache_hash.c
@@ -383,9 +383,9 @@ HSH_Lookup(struct sess *sp, struct objhead **poh)
 		 */
 		if (EXP_Grace(sp, o) >= sp->t_req) {
 			if (grace_oc == NULL ||
-			    grace_ttl < o->entered + o->exp.ttl) {
+			    grace_ttl < o->exp.entered + o->exp.ttl) {
 				grace_oc = oc;
-				grace_ttl = o->entered + o->exp.ttl;
+				grace_ttl = o->exp.entered + o->exp.ttl;
 			}
 		}
 	}
diff --git a/bin/varnishd/cache_response.c b/bin/varnishd/cache_response.c
index 4788a23..11f7fb6 100644
--- a/bin/varnishd/cache_response.c
+++ b/bin/varnishd/cache_response.c
@@ -226,7 +226,7 @@ RES_BuildHttp(struct sess *sp)
 		http_PrintfHeader(sp->wrk, sp->fd, sp->wrk->resp,
 		    "X-Varnish: %u", sp->xid);
 	http_PrintfHeader(sp->wrk, sp->fd, sp->wrk->resp, "Age: %.0f",
-	    sp->obj->age + sp->t_resp - sp->obj->entered);
+	    sp->obj->exp.age + sp->t_resp - sp->obj->exp.entered);
 	http_SetHeader(sp->wrk, sp->fd, sp->wrk->resp, "Via: 1.1 varnish");
 	http_PrintfHeader(sp->wrk, sp->fd, sp->wrk->resp, "Connection: %s",
 	    sp->doclose ? "close" : "keep-alive");
diff --git a/bin/varnishd/cache_vrt_var.c b/bin/varnishd/cache_vrt_var.c
index 297151c..1ee011b 100644
--- a/bin/varnishd/cache_vrt_var.c
+++ b/bin/varnishd/cache_vrt_var.c
@@ -360,15 +360,20 @@ VRT_r_req_restarts(const struct sess *sp)
 	return (sp->restarts);
 }
 
-/*--------------------------------------------------------------------*/
+/*--------------------------------------------------------------------
+ * NB: TTL is relative to when object was created, whereas grace and
+ * keep are relative to ttl.
+ */
 
-#define VRT_DO_EXP(which, exp, fld, extra)			\
+#define VRT_DO_EXP(which, exp, fld, offset, extra)		\
 								\
 void __match_proto__()						\
 VRT_l_##which##_##fld(struct sess *sp, double a)		\
 {								\
 								\
 	CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);			\
+	if (a > 0.)						\
+		a += offset;					\
 	EXP_Set_##fld(&exp, a);					\
 	extra;							\
 }								\
@@ -378,21 +383,37 @@ VRT_r_##which##_##fld(struct sess *sp)				\
 {								\
 								\
 	CHECK_OBJ_NOTNULL(sp, SESS_MAGIC);			\
-	return(EXP_Get_##fld(&exp));				\
-}
-
-VRT_DO_EXP(req, sp->exp, ttl, )
-VRT_DO_EXP(req, sp->exp, grace, )
-VRT_DO_EXP(req, sp->exp, keep, )
-VRT_DO_EXP(obj, sp->obj->exp, grace, EXP_Rearm(sp->obj))
-VRT_DO_EXP(obj, sp->obj->exp, ttl,
-	   EXP_Rearm(sp->obj);
-	   WSP(sp, SLT_TTL, "%u VCL %.0f %.0f", sp->obj->xid, a, sp->t_req))
-VRT_DO_EXP(obj, sp->obj->exp, keep, EXP_Rearm(sp->obj))
-VRT_DO_EXP(beresp, sp->wrk->exp, grace, )
-VRT_DO_EXP(beresp, sp->wrk->exp, ttl,
-	   WSP(sp, SLT_TTL, "%u VCL %.0f %.0f", sp->xid, a, sp->t_req))
-VRT_DO_EXP(beresp, sp->wrk->exp, keep, )
+	return(EXP_Get_##fld(&exp) - offset);			\
+}
+
+static void
+vrt_wsp_exp(const struct sess *sp, unsigned xid, const struct exp *e)
+{
+	WSP(sp, SLT_TTL, "%u VCL %.0f %.0f %.0f %.0f %.0f",
+	    xid, e->ttl - (sp->t_req - e->entered), e->grace, e->keep,
+	    sp->t_req, e->age + (sp->t_req - e->entered));
+}
+
+VRT_DO_EXP(req, sp->exp, ttl, 0, )
+VRT_DO_EXP(req, sp->exp, grace, 0, )
+VRT_DO_EXP(req, sp->exp, keep, 0, )
+
+VRT_DO_EXP(obj, sp->obj->exp, grace, 0,
+   EXP_Rearm(sp->obj);
+   vrt_wsp_exp(sp, sp->obj->xid, &sp->obj->exp);)
+VRT_DO_EXP(obj, sp->obj->exp, ttl, (sp->t_req - sp->obj->exp.entered),
+   EXP_Rearm(sp->obj);
+   vrt_wsp_exp(sp, sp->obj->xid, &sp->obj->exp);)
+VRT_DO_EXP(obj, sp->obj->exp, keep, 0,
+   EXP_Rearm(sp->obj);
+   vrt_wsp_exp(sp, sp->obj->xid, &sp->obj->exp);)
+
+VRT_DO_EXP(beresp, sp->wrk->exp, grace, 0,
+   vrt_wsp_exp(sp, sp->xid, &sp->wrk->exp);)
+VRT_DO_EXP(beresp, sp->wrk->exp, ttl, 0,
+   vrt_wsp_exp(sp, sp->xid, &sp->wrk->exp);)
+VRT_DO_EXP(beresp, sp->wrk->exp, keep, 0,
+   vrt_wsp_exp(sp, sp->xid, &sp->wrk->exp);)
 
 /*--------------------------------------------------------------------
  * req.xid
diff --git a/bin/varnishd/rfc2616.c b/bin/varnishd/rfc2616.c
index 7b2525f..69637ea 100644
--- a/bin/varnishd/rfc2616.c
+++ b/bin/varnishd/rfc2616.c
@@ -76,7 +76,7 @@ RFC2616_Ttl(const struct sess *sp)
 
 	hp = sp->wrk->beresp;
 
-	assert(sp->wrk->entered != 0.0 && !isnan(sp->wrk->entered));
+	assert(sp->wrk->exp.entered != 0.0 && !isnan(sp->wrk->exp.entered));
 	/* If all else fails, cache using default ttl */
 	ttl = params->default_ttl;
 
@@ -116,7 +116,7 @@ RFC2616_Ttl(const struct sess *sp)
 				max_age = strtoul(p, NULL, 0);
 			if (http_GetHdr(hp, H_Age, &p)) {
 				age = strtoul(p, NULL, 0);
-				sp->wrk->age = age;
+				sp->wrk->exp.age = age;
 			}
 
 			if (age > max_age)
@@ -145,16 +145,16 @@ RFC2616_Ttl(const struct sess *sp)
 		}
 
 		if (h_date == 0 ||
-		    fabs(h_date - sp->wrk->entered) < params->clock_skew) {
+		    fabs(h_date - sp->wrk->exp.entered) < params->clock_skew) {
 			/*
 			 * If we have no Date: header or if it is
 			 * sufficiently close to our clock we will
 			 * trust Expires: relative to our own clock.
 			 */
-			if (h_expires < sp->wrk->entered)
+			if (h_expires < sp->wrk->exp.entered)
 				ttl = 0;
 			else
-				ttl = h_expires - sp->wrk->entered;
+				ttl = h_expires - sp->wrk->exp.entered;
 			break;
 		} else {
 			/*
@@ -168,8 +168,10 @@ RFC2616_Ttl(const struct sess *sp)
 	}
 
 	/* calculated TTL, Our time, Date, Expires, max-age, age */
-	WSP(sp, SLT_TTL, "%u RFC %g %.0f %.0f %.0f %u %u", sp->xid,
-	    ttl, sp->wrk->entered, h_date, h_expires, max_age, age);
+	WSP(sp, SLT_TTL,
+	    "%u RFC %.0f %.0f %.0f %.0f %.0f %.0f %.0f %u %u",
+	    sp->xid, ttl, -1. -1., sp->wrk->exp.entered, sp->wrk->exp.age,
+	     h_date, h_expires, max_age);
 
 	return (ttl);
 }
diff --git a/bin/varnishd/stevedore.c b/bin/varnishd/stevedore.c
index 413e0b6..9a0b671 100644
--- a/bin/varnishd/stevedore.c
+++ b/bin/varnishd/stevedore.c
@@ -36,7 +36,6 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <math.h>
 
 #include "cache.h"
 #include "stevedore.h"
@@ -248,7 +247,6 @@ STV_MkObject(struct sess *sp, void *ptr, unsigned ltot,
 
 	http_Setup(o->http, o->ws_o);
 	o->http->magic = HTTP_MAGIC;
-	o->entered = NAN;
 	o->exp = *soc->exp;
 	VTAILQ_INIT(&o->store);
 	sp->wrk->stats.n_object++;
diff --git a/bin/varnishtest/tests/r00956.vtc b/bin/varnishtest/tests/r00956.vtc
new file mode 100644
index 0000000..c98996d
--- /dev/null
+++ b/bin/varnishtest/tests/r00956.vtc
@@ -0,0 +1,49 @@
+varnishtest "obj.ttl relative/absolute"
+
+server s1 {
+	rxreq
+	txresp -hdr "Cache-Control: max-age=23" -hdr "Age: 4" -bodylen 40
+} -start
+
+varnish v1 -vcl+backend {
+	sub vcl_fetch {
+		set beresp.ttl = 10s;
+		set req.http.foo = beresp.ttl;
+		set req.http.bar = "xxx";
+	}
+	sub vcl_hit {
+		set req.http.foo = obj.ttl;
+		set obj.ttl = 7s;
+		set obj.grace = 120s;
+		set obj.keep = 1h;
+		set req.http.bar = obj.ttl;
+	}
+	sub vcl_deliver {
+		set resp.http.foo = req.http.foo;
+		set resp.http.bar = req.http.bar;
+	}
+} -start
+
+client c1 {
+	txreq
+	rxresp
+	expect resp.bodylen == 40
+	expect resp.http.foo == 10.000
+	expect resp.http.bar == "xxx"
+
+	delay 2
+	txreq
+	rxresp
+	expect resp.bodylen == 40
+	# XXX: should be: < 8
+	expect resp.http.foo != 10.000
+	expect resp.http.bar == 7.000
+
+	delay 2
+	txreq
+	rxresp
+	expect resp.bodylen == 40
+	# XXX: should be: < 5
+	expect resp.http.foo != 7.000
+	expect resp.http.bar == 7.000
+} -run



More information about the varnish-commit mailing list