[master] 2eb5e55 Move all of cnt_fetch() to cache_fetch.c

Poul-Henning Kamp phk at varnish-cache.org
Mon May 20 12:44:32 CEST 2013


commit 2eb5e555f796caa9d05523a0fd044ecf91e60a0b
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Mon May 20 10:44:10 2013 +0000

    Move all of cnt_fetch() to cache_fetch.c

diff --git a/bin/varnishd/cache/cache.h b/bin/varnishd/cache/cache.h
index 3d47cd8..18155e8 100644
--- a/bin/varnishd/cache/cache.h
+++ b/bin/varnishd/cache/cache.h
@@ -816,7 +816,6 @@ int VBF_Fetch(struct worker *wrk, struct req *req);
 struct storage *FetchStorage(struct busyobj *, ssize_t sz);
 int FetchError(struct busyobj *, const char *error);
 int FetchError2(struct busyobj *, const char *error, const char *more);
-int FetchHdr(struct worker *wrk, struct busyobj *bo, struct req *req);
 void Fetch_Init(void);
 
 /* cache_gzip.c */
diff --git a/bin/varnishd/cache/cache_fetch.c b/bin/varnishd/cache/cache_fetch.c
index f42f62a..3e88210 100644
--- a/bin/varnishd/cache/cache_fetch.c
+++ b/bin/varnishd/cache/cache_fetch.c
@@ -40,6 +40,7 @@
 
 #include "cache_backend.h"
 #include "vcli_priv.h"
+#include "vcl.h"
 #include "vct.h"
 #include "vtcp.h"
 #include "vtim.h"
@@ -358,7 +359,7 @@ fetch_iter_req_body(struct req *req, void *priv, void *ptr, size_t l)
  *	 1 failure which can be retried.
  */
 
-int
+static int
 FetchHdr(struct worker *wrk, struct busyobj *bo, struct req *req)
 {
 	struct vbc *vc;
@@ -628,6 +629,146 @@ FetchBody(struct worker *wrk, void *priv)
 /*--------------------------------------------------------------------
  */
 
+static int
+cnt_fetch(struct worker *wrk, struct req *req, struct busyobj *bo)
+{
+	int i;
+
+	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
+	CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
+
+	CHECK_OBJ_NOTNULL(bo->vcl, VCL_CONF_MAGIC);
+	CHECK_OBJ_NOTNULL(req->objcore, OBJCORE_MAGIC);
+
+	bo = req->busyobj;
+	CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
+
+	AN(req->director);
+	AZ(bo->vbc);
+	AZ(bo->should_close);
+	AZ(bo->storage_hint);
+
+	HTTP_Setup(bo->bereq, bo->ws, bo->vsl, HTTP_Bereq);
+	http_FilterReq(bo->bereq, req->http,
+	    bo->do_pass ? HTTPH_R_PASS : HTTPH_R_FETCH);
+	if (!bo->do_pass) {
+		http_ForceGet(bo->bereq);
+		if (cache_param->http_gzip_support) {
+			/*
+			 * We always ask the backend for gzip, even if the
+			 * client doesn't grok it.  We will uncompress for
+			 * the minority of clients which don't.
+			 */
+			http_Unset(bo->bereq, H_Accept_Encoding);
+			http_SetHeader(bo->bereq, "Accept-Encoding: gzip");
+		}
+	}
+
+	VCL_backend_fetch_method(bo->vcl, wrk, NULL, bo, bo->bereq->ws);
+	xxxassert (wrk->handling == VCL_RET_FETCH);
+
+	http_PrintfHeader(bo->bereq,
+	    "X-Varnish: %u", req->vsl->wid & VSL_IDENTMASK);
+
+	HTTP_Setup(bo->beresp, bo->ws, bo->vsl, HTTP_Beresp);
+
+	req->acct_req.fetch++;
+
+	i = FetchHdr(wrk, bo, req->objcore->objhead == NULL ? req : NULL);
+	/*
+	 * If we recycle a backend connection, there is a finite chance
+	 * that the backend closed it before we get a request to it.
+	 * Do a single retry in that case.
+	 */
+	if (i == 1) {
+		VSC_C_main->backend_retry++;
+		i = FetchHdr(wrk, bo,
+		    req->objcore->objhead == NULL ? req : NULL);
+	}
+
+	if (req->objcore->objhead != NULL)
+		(void)HTTP1_DiscardReqBody(req);	// XXX
+
+	if (i) {
+		wrk->handling = VCL_RET_ERROR;
+		req->err_code = 503;
+	} else {
+		/*
+		 * These two headers can be spread over multiple actual headers
+		 * and we rely on their content outside of VCL, so collect them
+		 * into one line here.
+		 */
+		http_CollectHdr(bo->beresp, H_Cache_Control);
+		http_CollectHdr(bo->beresp, H_Vary);
+
+		/*
+		 * Figure out how the fetch is supposed to happen, before the
+		 * headers are adultered by VCL
+		 * NB: Also sets other wrk variables
+		 */
+		bo->htc.body_status = RFC2616_Body(bo, &wrk->stats);
+
+		req->err_code = http_GetStatus(bo->beresp);
+
+		/*
+		 * What does RFC2616 think about TTL ?
+		 */
+		EXP_Clr(&bo->exp);
+		bo->exp.entered = W_TIM_real(wrk);
+		RFC2616_Ttl(bo);
+
+		/* pass from vclrecv{} has negative TTL */
+		if (req->objcore->objhead == NULL)
+			bo->exp.ttl = -1.;
+
+		AZ(bo->do_esi);
+
+		VCL_backend_response_method(bo->vcl, wrk, NULL, bo,
+		    bo->beresp->ws);
+
+		if (bo->do_pass)
+			req->objcore->flags |= OC_F_PASS;
+
+		switch (wrk->handling) {
+		case VCL_RET_DELIVER:
+			return (0);
+		default:
+			break;
+		}
+
+		/* We are not going to fetch the body, Close the connection */
+		VDI_CloseFd(&bo->vbc);
+	}
+
+	/* Clean up partial fetch */
+	AZ(bo->vbc);
+
+	if (req->objcore->objhead != NULL ||
+	    wrk->handling == VCL_RET_RESTART ||
+	    wrk->handling == VCL_RET_ERROR) {
+		CHECK_OBJ_NOTNULL(req->objcore, OBJCORE_MAGIC);
+		AZ(HSH_Deref(&wrk->stats, req->objcore, NULL));
+		req->objcore = NULL;
+	}
+	assert(bo->refcount == 2);
+	bo->storage_hint = NULL;
+	VBO_DerefBusyObj(wrk, &bo);
+	VBO_DerefBusyObj(wrk, &req->busyobj);
+	req->director = NULL;
+
+	switch (wrk->handling) {
+	case VCL_RET_RESTART:
+		// req->req_step = R_STP_RESTART;
+		return (1);
+	case VCL_RET_ERROR:
+		// req->req_step = R_STP_ERROR;
+		return (-1);
+	default:
+		WRONG("Illegal action in vcl_fetch{}");
+	}
+}
+
+
 int
 VBF_Fetch(struct worker *wrk, struct req *req)
 {
@@ -638,6 +779,7 @@ VBF_Fetch(struct worker *wrk, struct req *req)
 	struct vsb *vary = NULL;
 	int varyl = 0, pass;
 	struct busyobj *bo;
+	int i;
 
 	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
 	CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
@@ -645,6 +787,10 @@ VBF_Fetch(struct worker *wrk, struct req *req)
 	bo = req->busyobj;
 	CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
 
+	i = cnt_fetch(wrk, req, bo);
+	if (i)
+		return (i);
+
 	if (req->objcore->objhead == NULL) {
 		/* This is a pass from vcl_recv */
 		pass = 1;
diff --git a/bin/varnishd/cache/cache_req_fsm.c b/bin/varnishd/cache/cache_req_fsm.c
index 6dd3518..04e3415 100644
--- a/bin/varnishd/cache/cache_req_fsm.c
+++ b/bin/varnishd/cache/cache_req_fsm.c
@@ -335,160 +335,6 @@ cnt_error(struct worker *wrk, struct req *req)
 }
 
 /*--------------------------------------------------------------------
- * Fetch response headers from the backend
- *
-DOT subgraph xcluster_fetch {
-DOT	fetch [
-DOT		shape=record
-DOT		label="{cnt_fetch:|fetch hdr\nfrom backend|(find obj.ttl)|{vcl_fetch\{\}|{req.|bereq.|beresp.}}|{<err>error?|<rst>restart?}}"
-DOT	]
-DOT }
-DOT fetch -> fetchbody [style=bold,color=red]
-DOT fetch -> fetchbody [style=bold,color=blue]
- */
-
-static enum req_fsm_nxt
-cnt_fetch(struct worker *wrk, struct req *req)
-{
-	int i;
-	struct busyobj *bo;
-
-	CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
-	CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
-
-	CHECK_OBJ_NOTNULL(req->vcl, VCL_CONF_MAGIC);
-	CHECK_OBJ_NOTNULL(req->objcore, OBJCORE_MAGIC);
-
-	bo = req->busyobj;
-	CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
-
-	AN(req->director);
-	AZ(bo->vbc);
-	AZ(bo->should_close);
-	AZ(bo->storage_hint);
-
-	HTTP_Setup(bo->bereq, bo->ws, bo->vsl, HTTP_Bereq);
-	http_FilterReq(bo->bereq, req->http,
-	    bo->do_pass ? HTTPH_R_PASS : HTTPH_R_FETCH);
-	if (!bo->do_pass) {
-		http_ForceGet(bo->bereq);
-		if (cache_param->http_gzip_support) {
-			/*
-			 * We always ask the backend for gzip, even if the
-			 * client doesn't grok it.  We will uncompress for
-			 * the minority of clients which don't.
-			 */
-			http_Unset(bo->bereq, H_Accept_Encoding);
-			http_SetHeader(bo->bereq, "Accept-Encoding: gzip");
-		}
-	}
-
-	VCL_backend_fetch_method(bo->vcl, wrk, NULL, bo, bo->bereq->ws);
-	xxxassert (wrk->handling == VCL_RET_FETCH);
-
-	http_PrintfHeader(bo->bereq,
-	    "X-Varnish: %u", req->vsl->wid & VSL_IDENTMASK);
-
-	HTTP_Setup(bo->beresp, bo->ws, bo->vsl, HTTP_Beresp);
-
-	req->acct_req.fetch++;
-
-	i = FetchHdr(wrk, bo, req->objcore->objhead == NULL ? req : NULL);
-	/*
-	 * If we recycle a backend connection, there is a finite chance
-	 * that the backend closed it before we get a request to it.
-	 * Do a single retry in that case.
-	 */
-	if (i == 1) {
-		VSC_C_main->backend_retry++;
-		i = FetchHdr(wrk, bo,
-		    req->objcore->objhead == NULL ? req : NULL);
-	}
-
-	if (req->objcore->objhead != NULL)
-		(void)HTTP1_DiscardReqBody(req);	// XXX
-
-	if (i) {
-		wrk->handling = VCL_RET_ERROR;
-		req->err_code = 503;
-	} else {
-		/*
-		 * These two headers can be spread over multiple actual headers
-		 * and we rely on their content outside of VCL, so collect them
-		 * into one line here.
-		 */
-		http_CollectHdr(bo->beresp, H_Cache_Control);
-		http_CollectHdr(bo->beresp, H_Vary);
-
-		/*
-		 * Figure out how the fetch is supposed to happen, before the
-		 * headers are adultered by VCL
-		 * NB: Also sets other wrk variables
-		 */
-		bo->htc.body_status = RFC2616_Body(bo, &wrk->stats);
-
-		req->err_code = http_GetStatus(bo->beresp);
-
-		/*
-		 * What does RFC2616 think about TTL ?
-		 */
-		EXP_Clr(&bo->exp);
-		bo->exp.entered = W_TIM_real(wrk);
-		RFC2616_Ttl(bo);
-
-		/* pass from vclrecv{} has negative TTL */
-		if (req->objcore->objhead == NULL)
-			bo->exp.ttl = -1.;
-
-		AZ(bo->do_esi);
-
-		VCL_backend_response_method(bo->vcl, wrk, NULL, bo,
-		    bo->beresp->ws);
-
-		if (bo->do_pass)
-			req->objcore->flags |= OC_F_PASS;
-
-		switch (wrk->handling) {
-		case VCL_RET_DELIVER:
-			req->req_step = R_STP_FETCHBODY;
-			return (REQ_FSM_MORE);
-		default:
-			break;
-		}
-
-		/* We are not going to fetch the body, Close the connection */
-		VDI_CloseFd(&bo->vbc);
-	}
-
-	/* Clean up partial fetch */
-	AZ(bo->vbc);
-
-	if (req->objcore->objhead != NULL ||
-	    wrk->handling == VCL_RET_RESTART ||
-	    wrk->handling == VCL_RET_ERROR) {
-		CHECK_OBJ_NOTNULL(req->objcore, OBJCORE_MAGIC);
-		AZ(HSH_Deref(&wrk->stats, req->objcore, NULL));
-		req->objcore = NULL;
-	}
-	assert(bo->refcount == 2);
-	bo->storage_hint = NULL;
-	VBO_DerefBusyObj(wrk, &bo);
-	VBO_DerefBusyObj(wrk, &req->busyobj);
-	req->director = NULL;
-
-	switch (wrk->handling) {
-	case VCL_RET_RESTART:
-		req->req_step = R_STP_RESTART;
-		return (REQ_FSM_MORE);
-	case VCL_RET_ERROR:
-		req->req_step = R_STP_ERROR;
-		return (REQ_FSM_MORE);
-	default:
-		WRONG("Illegal action in vcl_fetch{}");
-	}
-}
-
-/*--------------------------------------------------------------------
  * Prepare to fetch body from backend
  *
 DOT subgraph xcluster_body {
@@ -502,7 +348,7 @@ DOT fetchbody:out -> prepresp [style=bold,color=blue]
  */
 
 static enum req_fsm_nxt
-cnt_fetchbody(struct worker *wrk, struct req *req)
+cnt_fetch(struct worker *wrk, struct req *req)
 {
 	int i;
 
@@ -513,6 +359,8 @@ cnt_fetchbody(struct worker *wrk, struct req *req)
 	if (i < 0) {
 		req->err_code = 503;
 		req->req_step = R_STP_ERROR;
+	} else if (i == 1) {
+		req->req_step = R_STP_RESTART;
 	} else {
 		assert(WRW_IsReleased(wrk));
 		req->req_step = R_STP_PREPRESP;
@@ -705,8 +553,12 @@ cnt_miss(struct worker *wrk, struct req *req)
 	AZ(req->obj);
 	AZ(req->busyobj);
 
-	/* We optimistically expect to need this most of the time */
+	/*
+	 * We optimistically expect to need this most of the time
+	 * (This allows us to put the predictive Vary directly on the bo->ws)
+	 */
 	bo = VBO_GetBusyObj(wrk, req);
+	CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
 	req->busyobj = bo;
 	VRY_Finish(req, bo);
 
@@ -743,7 +595,6 @@ cnt_miss(struct worker *wrk, struct req *req)
 	req->objcore->busyobj = bo;
 	wrk->stats.cache_miss++;
 
-	CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
 	req->req_step = R_STP_FETCH;
 	return (REQ_FSM_MORE);
 }
@@ -788,14 +639,14 @@ cnt_pass(struct worker *wrk, struct req *req)
 	assert (wrk->handling == VCL_RET_FETCH);
 	req->acct_req.pass++;
 
-	req->busyobj = VBO_GetBusyObj(wrk, req);
-	bo = req->busyobj;
+	bo = VBO_GetBusyObj(wrk, req);
+	CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
+	req->busyobj = bo;
 	bo->do_pass = 1;
 	req->objcore = HSH_NewObjCore(wrk);
 	req->objcore->busyobj = bo;
 	bo->refcount = 2;
 
-	CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
 	req->req_step = R_STP_FETCH;
 	return (REQ_FSM_MORE);
 }
diff --git a/include/tbl/steps.h b/include/tbl/steps.h
index a4c19b0..6c3f3f6 100644
--- a/include/tbl/steps.h
+++ b/include/tbl/steps.h
@@ -44,7 +44,6 @@ REQ_STEP(lookup,	LOOKUP,		(wrk, req))
 REQ_STEP(purge,		PURGE,		(wrk, req))
 REQ_STEP(miss,		MISS,		(wrk, req))
 REQ_STEP(fetch,		FETCH,		(wrk, req))
-REQ_STEP(fetchbody,	FETCHBODY,	(wrk, req))
 REQ_STEP(prepresp,	PREPRESP,	(wrk, req))
 REQ_STEP(deliver,	DELIVER,	(wrk, req))
 REQ_STEP(error,		ERROR,		(wrk, req))



More information about the varnish-commit mailing list