r2167 - in trunk/varnish-cache: bin/varnishd include lib/libvcl

phk at projects.linpro.no phk at projects.linpro.no
Wed Oct 24 16:32:12 CEST 2007


Author: phk
Date: 2007-10-24 16:32:12 +0200 (Wed, 24 Oct 2007)
New Revision: 2167

Modified:
   trunk/varnish-cache/bin/varnishd/cache.h
   trunk/varnish-cache/bin/varnishd/cache_acceptor.c
   trunk/varnish-cache/bin/varnishd/cache_center.c
   trunk/varnish-cache/bin/varnishd/cache_httpconn.c
   trunk/varnish-cache/bin/varnishd/cache_session.c
   trunk/varnish-cache/bin/varnishd/cache_vrt.c
   trunk/varnish-cache/bin/varnishd/cache_ws.c
   trunk/varnish-cache/include/vrt.h
   trunk/varnish-cache/lib/libvcl/vcc_action.c
   trunk/varnish-cache/lib/libvcl/vcc_fixed_token.c
Log:
Gently shuffle closer to being able to restart a esi:include on the next
element:

Add two checkpoints for the sessions workspace.

The first checkpoint is after the session fixed data, and move the
client address and port to workspace to see that this works.

The second checkpoint is after the, as received unadultered by VCL
http request.  Grab a copy of the http request matching this.

Implement rollback as an optional feature of restart in VCL.

Move various workspace initialization and resetting operations to more
suitable locations in the program flow.

I don't know if this is really usable, but now it's possible to do:

	backend b1 {
		set backend.host = "backend1";
		set backend.port = "80";
	}

	backend b2 {
		set backend.host = "backend2";
		set backend.port = "80";
	}

	sub vcl_recv {
		set req.backend = b1;
		remove req.http.cookie;

		if (req.restarts == 0) {
			set req.url = "foobar.html";
		} else {
			set req.backend = b2;
		}
	}

	sub vcl_fetch {
		if (obj.status != 200) {
			restart rollback;
		}
	}

And have it first look for "foobar.html" on one backend, and failing
that, try to give the user what they asked for from the other backend.


Modified: trunk/varnish-cache/bin/varnishd/cache.h
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache.h	2007-10-24 10:24:08 UTC (rev 2166)
+++ trunk/varnish-cache/bin/varnishd/cache.h	2007-10-24 14:32:12 UTC (rev 2167)
@@ -288,14 +288,18 @@
 	struct sockaddr		*mysockaddr;
 
 	/* formatted ascii client address */
-	char			addr[TCP_ADDRBUFSIZE];
-	char			port[TCP_PORTBUFSIZE];
+	char			*addr;
+	char			*port;
 	struct srcaddr		*srcaddr;
 
 	/* HTTP request */
 	const char		*doclose;
 	struct http		*http;
+	struct http		*http0;
+
 	struct ws		ws[1];
+	char			*ws_ses;	/* WS above session data */
+	char			*ws_req;	/* WS above request data */
 
 	struct http_conn	htc[1];
 
@@ -583,9 +587,10 @@
 void WS_Release(struct ws *ws, unsigned bytes);
 void WS_ReleaseP(struct ws *ws, char *ptr);
 void WS_Assert(const struct ws *ws);
-void WS_Reset(struct ws *ws);
+void WS_Reset(struct ws *ws, char *p);
 char *WS_Alloc(struct ws *ws, unsigned bytes);
 char *WS_Dup(struct ws *ws, const char *);
+char *WS_Snapshot(struct ws *ws);
 
 /* rfc2616.c */
 int RFC2616_cache_policy(const struct sess *sp, const struct http *hp);

Modified: trunk/varnish-cache/bin/varnishd/cache_acceptor.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_acceptor.c	2007-10-24 10:24:08 UTC (rev 2166)
+++ trunk/varnish-cache/bin/varnishd/cache_acceptor.c	2007-10-24 14:32:12 UTC (rev 2167)
@@ -107,9 +107,14 @@
 void
 VCA_Prep(struct sess *sp)
 {
+	char addr[TCP_ADDRBUFSIZE];
+	char port[TCP_PORTBUFSIZE];
 
+
 	TCP_name(sp->sockaddr, sp->sockaddrlen,
-	    sp->addr, sizeof sp->addr, sp->port, sizeof sp->port);
+	    addr, sizeof addr, port, sizeof port);
+	sp->addr = WS_Dup(sp->ws, addr);
+	sp->port = WS_Dup(sp->ws, port);
 	VSL(SLT_SessionOpen, sp->fd, "%s %s", sp->addr, sp->port);
 	sp->acct.first = sp->t_open;
 	if (need_test)
@@ -195,7 +200,6 @@
 			sp->id = i;
 			sp->t_open = now;
 
-			HTC_Init(sp->htc, sp->ws, sp->fd);
 			sp->step = STP_FIRST;
 			WRK_QueueSession(sp);
 		}

Modified: trunk/varnish-cache/bin/varnishd/cache_center.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_center.c	2007-10-24 10:24:08 UTC (rev 2166)
+++ trunk/varnish-cache/bin/varnishd/cache_center.c	2007-10-24 14:32:12 UTC (rev 2167)
@@ -221,6 +221,9 @@
 		return (1);
 	}
 
+	/* Reset the workspace to the session-watermark */
+	WS_Reset(sp->ws, sp->ws_ses);
+
 	i = HTC_Reinit(sp->htc);
 	if (i == 1) {
 		VSL_stats->sess_pipeline++;
@@ -368,12 +371,19 @@
 
 	assert(sp->xid == 0);
 	VCA_Prep(sp);
+
+	/* Record the session watermark */
+	sp->ws_ses = WS_Snapshot(sp->ws);
+
+	/* Receive a HTTP protocol request */
+	HTC_Init(sp->htc, sp->ws, sp->fd);
 	sp->wrk->used = sp->t_open;
 	sp->wrk->acct.sess++;
 	SES_RefSrcAddr(sp);
 	do
 		i = HTC_Rx(sp->htc);
 	while (i == 0);
+
 	switch (i) {
 	case 1:
 		sp->step = STP_RECV;
@@ -734,7 +744,15 @@
 		sp->vcl = sp->wrk->vcl;
 		sp->wrk->vcl = NULL;
 
+		http_Setup(sp->http, sp->ws);
 		done = http_DissectRequest(sp);
+
+		/* Catch request snapshot */
+		sp->ws_req = WS_Snapshot(sp->ws);
+
+		/* Catch original request, before modification */
+		*sp->http0 = *sp->http;
+
 		if (done != 0) {
 			RES_Error(sp, done, NULL);		/* XXX: STP_ERROR ? */
 			sp->step = STP_DONE;

Modified: trunk/varnish-cache/bin/varnishd/cache_httpconn.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_httpconn.c	2007-10-24 10:24:08 UTC (rev 2166)
+++ trunk/varnish-cache/bin/varnishd/cache_httpconn.c	2007-10-24 14:32:12 UTC (rev 2167)
@@ -86,7 +86,6 @@
 	htc->magic = HTTP_CONN_MAGIC;
 	htc->ws = ws;
 	htc->fd = fd;
-	WS_Reset(htc->ws);
 	WS_Reserve(htc->ws, (htc->ws->e - htc->ws->s) / 2);
 	htc->rxbuf.b = ws->f;
 	htc->rxbuf.e = ws->f;
@@ -107,7 +106,6 @@
 	int i;
 
 	CHECK_OBJ_NOTNULL(htc, HTTP_CONN_MAGIC);
-	WS_Reset(htc->ws);
 	WS_Reserve(htc->ws, (htc->ws->e - htc->ws->s) / 2);
 	htc->rxbuf.b = htc->ws->f;
 	htc->rxbuf.e = htc->ws->f;

Modified: trunk/varnish-cache/bin/varnishd/cache_session.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_session.c	2007-10-24 10:24:08 UTC (rev 2166)
+++ trunk/varnish-cache/bin/varnishd/cache_session.c	2007-10-24 14:32:12 UTC (rev 2167)
@@ -65,7 +65,7 @@
 #define SESSMEM_MAGIC		0x555859c5
 
 	struct sess		sess;
-	struct http		http;
+	struct http		http[2];
 	unsigned		workspace;
 	VTAILQ_ENTRY(sessmem)	list;
 	struct sockaddr_storage	sockaddr[2];
@@ -319,8 +319,8 @@
 	}
 
 	WS_Init(sp->ws, (void *)(sm + 1), sm->workspace);
-	sp->http = &sm->http;
-	http_Setup(sp->http, sp->ws);
+	sp->http = &sm->http[0];
+	sp->http0 = &sm->http[1];
 
 	return (sp);
 }

Modified: trunk/varnish-cache/bin/varnishd/cache_vrt.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_vrt.c	2007-10-24 10:24:08 UTC (rev 2166)
+++ trunk/varnish-cache/bin/varnishd/cache_vrt.c	2007-10-24 14:32:12 UTC (rev 2167)
@@ -510,6 +510,16 @@
 /*--------------------------------------------------------------------*/
 
 void
+VRT_Rollback(struct sess *sp)
+{
+
+	*sp->http = *sp->http0;
+	WS_Reset(sp->ws, sp->ws_req);
+}
+	
+/*--------------------------------------------------------------------*/
+
+void
 VRT_purge(const char *regexp, int hash)
 {
 	

Modified: trunk/varnish-cache/bin/varnishd/cache_ws.c
===================================================================
--- trunk/varnish-cache/bin/varnishd/cache_ws.c	2007-10-24 10:24:08 UTC (rev 2166)
+++ trunk/varnish-cache/bin/varnishd/cache_ws.c	2007-10-24 14:32:12 UTC (rev 2167)
@@ -74,12 +74,18 @@
 }
 
 void
-WS_Reset(struct ws *ws)
+WS_Reset(struct ws *ws, char *p)
 {
 
 	WS_Assert(ws);
 	assert(ws->r == NULL);
-	ws->f = ws->s;
+	if (p == NULL)
+		ws->f = ws->s;
+	else {
+		assert(p >= ws->s);
+		assert(p < ws->e);
+		ws->f = p;
+	}
 }
 
 char *
@@ -109,6 +115,14 @@
 	return (p);
 }
 
+char *
+WS_Snapshot(struct ws *ws)
+{
+
+	assert(ws->r == NULL);
+	return (ws->f);
+}
+
 unsigned
 WS_Reserve(struct ws *ws, unsigned bytes)
 {

Modified: trunk/varnish-cache/include/vrt.h
===================================================================
--- trunk/varnish-cache/include/vrt.h	2007-10-24 10:24:08 UTC (rev 2166)
+++ trunk/varnish-cache/include/vrt.h	2007-10-24 14:32:12 UTC (rev 2167)
@@ -114,8 +114,8 @@
 int VRT_strcmp(const char *s1, const char *s2);
 
 void VRT_ESI(struct sess *sp);
+void VRT_Rollback(struct sess *sp);
 
-
 /* Backend related */
 void VRT_init_simple_backend(struct backend **, const struct vrt_simple_backend *);
 void VRT_init_round_robin_backend(struct backend **, const struct vrt_round_robin_backend *);

Modified: trunk/varnish-cache/lib/libvcl/vcc_action.c
===================================================================
--- trunk/varnish-cache/lib/libvcl/vcc_action.c	2007-10-24 10:24:08 UTC (rev 2166)
+++ trunk/varnish-cache/lib/libvcl/vcc_action.c	2007-10-24 14:32:12 UTC (rev 2167)
@@ -55,6 +55,25 @@
 /*--------------------------------------------------------------------*/
 
 static void
+parse_restart_real(struct tokenlist *tl)
+{
+	struct token *t1;
+	
+	t1 = VTAILQ_NEXT(tl->t, list);
+	if (t1->tok == ID && vcc_IdIs(t1, "rollback")) {
+		Fb(tl, 1, "VRT_Rollback(sp);\n");
+		vcc_NextToken(tl);
+	} else if (t1->tok != ';') {
+		vsb_printf(tl->sb, "Expected \"rollback\" or semicolon.\n");
+		vcc_ErrWhere(tl, t1);
+		ERRCHK(tl);
+	}
+	parse_restart(tl);
+}
+
+/*--------------------------------------------------------------------*/
+
+static void
 parse_call(struct tokenlist *tl)
 {
 
@@ -333,6 +352,7 @@
 	const char		*name;
 	action_f		*func;
 } action_table[] = {
+	{ "restart",	parse_restart_real },
 #define VCL_RET_MAC(l, u, b, i) { #l, parse_##l },
 #define VCL_RET_MAC_E(l, u, b, i) VCL_RET_MAC(l, u, b, i) 
 #include "vcl_returns.h"

Modified: trunk/varnish-cache/lib/libvcl/vcc_fixed_token.c
===================================================================
--- trunk/varnish-cache/lib/libvcl/vcc_fixed_token.c	2007-10-24 10:24:08 UTC (rev 2166)
+++ trunk/varnish-cache/lib/libvcl/vcc_fixed_token.c	2007-10-24 14:32:12 UTC (rev 2167)
@@ -493,8 +493,8 @@
 	vsb_cat(sb, "int VRT_strcmp(const char *s1, const char *s2);\n");
 	vsb_cat(sb, "\n");
 	vsb_cat(sb, "void VRT_ESI(struct sess *sp);\n");
+	vsb_cat(sb, "void VRT_Rollback(struct sess *sp);\n");
 	vsb_cat(sb, "\n");
-	vsb_cat(sb, "\n");
 	vsb_cat(sb, "/* Backend related */\n");
 	vsb_cat(sb, "void VRT_init_simple_backend(struct backend **, const struct vrt_simple_backend *);\n");
 	vsb_cat(sb, "void VRT_init_round_robin_backend(struct backend **, const struct vrt_round_robin_backend *);\n");




More information about the varnish-commit mailing list