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