[master] eba445d Restructure to put all the streaming code in one place.
Poul-Henning Kamp
phk at varnish-cache.org
Wed Aug 21 10:11:28 CEST 2013
commit eba445d4621c6e4819611f3f064da0a492b519f7
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date: Wed Aug 21 08:11:16 2013 +0000
Restructure to put all the streaming code in one place.
diff --git a/bin/varnishd/cache/cache_req_fsm.c b/bin/varnishd/cache/cache_req_fsm.c
index bb52290..db27c51 100644
--- a/bin/varnishd/cache/cache_req_fsm.c
+++ b/bin/varnishd/cache/cache_req_fsm.c
@@ -79,43 +79,102 @@ DOT acceptor -> recv [style=bold,color=green]
* We have a refcounted object on the session, and possibly the busyobj
* which is fetching it, prepare a response.
*
-DOT subgraph xcluster_prepresp {
-DOT prepresp [
+DOT stream [
DOT shape=record
-DOT label="{cnt_prepresp:|Filter obj.-\>resp.|{vcl_deliver\{\}|{req.|resp.}}|{error?|restart?}|stream ?}"
+DOT label="{cnt_stream:}"
DOT ]
-DOT prepresp -> deliver [style=bold,color=green,label=deliver]
-DOT prepresp -> deliver [style=bold,color=red]
-DOT prepresp -> deliver [style=bold,color=blue]
-DOT }
+DOT stream:deliver:s -> DONE [style=bold,color=red]
+DOT stream:deliver:s -> DONE [style=bold,color=blue]
*
*/
static enum req_fsm_nxt
-cnt_prepresp(struct worker *wrk, struct req *req)
+cnt_stream(struct worker *wrk, struct req *req)
{
struct busyobj *bo;
CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
bo = req->busyobj;
- CHECK_OBJ_ORNULL(bo, BUSYOBJ_MAGIC);
+ CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
CHECK_OBJ_NOTNULL(req->obj, OBJECT_MAGIC);
CHECK_OBJ_NOTNULL(req->vcl, VCL_CONF_MAGIC);
req->res_mode = 0;
- if (bo == NULL) {
- if (!req->disable_esi && req->obj->esidata != NULL) {
- /* In ESI mode, we can't know the aggregate length */
- req->res_mode &= ~RES_LEN;
- req->res_mode |= RES_ESI;
- } else {
- req->res_mode |= RES_LEN;
- }
+ AZ(bo->do_esi);
+
+ if (wrk->handling == VCL_RET_RESTART) {
+ AN(bo->do_stream);
+ assert(req->obj == bo->fetch_obj);
+ req->obj = NULL;
+ VBO_DerefBusyObj(wrk, &req->busyobj);
+ AZ(req->obj);
+ http_Teardown(req->resp);
+ req->req_step = R_STP_RESTART;
+ return (REQ_FSM_MORE);
+ }
+ assert(wrk->handling == VCL_RET_DELIVER);
+
+ while (bo->state < BOS_FAILED)
+ (void)usleep(10000);
+ assert(bo->state >= BOS_FAILED);
+
+ if (bo->state == BOS_FAILED) {
+ (void)HSH_Deref(&wrk->stats, NULL, &req->obj);
+ VBO_DerefBusyObj(wrk, &req->busyobj);
+ req->err_code = 503;
+ req->req_step = R_STP_ERROR;
+ return (REQ_FSM_MORE);
+ }
+ VBO_DerefBusyObj(wrk, &req->busyobj);
+
+ AZ(req->busyobj);
+
+ RES_WriteObj(req);
+
+ /* No point in saving the body if it is hit-for-pass */
+ if (req->obj->objcore->flags & OC_F_PASS)
+ STV_Freestore(req->obj);
+
+ assert(WRW_IsReleased(wrk));
+ (void)HSH_Deref(&wrk->stats, NULL, &req->obj);
+ http_Teardown(req->resp);
+ return (REQ_FSM_DONE);
+}
+
+/*--------------------------------------------------------------------
+ * Deliver an already stored object
+ *
+DOT deliver [
+DOT shape=record
+DOT label="{cnt_deliver:|Filter obj.-\>resp.|{vcl_deliver\{\}|{req.|resp.}}|{<stream>deliver(stream)?|restart?|<deliver>deliver?}}"
+DOT ]
+DOT deliver:deliver:s -> DONE [style=bold,color=green]
+DOT deliver:stream:s -> stream [style=bold,color=red]
+DOT deliver:stream:s -> stream [style=bold,color=blue]
+ *
+ */
+
+static enum req_fsm_nxt
+cnt_deliver(struct worker *wrk, struct req *req)
+{
+
+ CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
+ CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
+ CHECK_OBJ_NOTNULL(req->obj, OBJECT_MAGIC);
+ CHECK_OBJ_NOTNULL(req->vcl, VCL_CONF_MAGIC);
+
+ req->res_mode = 0;
+
+ if (!req->disable_esi && req->obj->esidata != NULL) {
+ AZ(req->busyobj);
+ /* In ESI mode, we can't know the aggregate length */
+ req->res_mode &= ~RES_LEN;
+ req->res_mode |= RES_ESI;
} else {
- AZ(bo->do_esi);
+ req->res_mode |= RES_LEN;
}
if (req->esi_level > 0) {
@@ -159,75 +218,24 @@ cnt_prepresp(struct worker *wrk, struct req *req)
RES_BuildHttp(req);
VCL_deliver_method(req->vcl, wrk, req, NULL, req->http->ws);
- switch (wrk->handling) {
- case VCL_RET_DELIVER:
- break;
- case VCL_RET_RESTART:
- if (req->restarts >= cache_param->max_restarts)
- break;
- if (bo != NULL) {
- AN(bo->do_stream);
- assert(req->obj == bo->fetch_obj);
- req->obj = NULL;
- VBO_DerefBusyObj(wrk, &req->busyobj);
- } else {
- (void)HSH_Deref(&wrk->stats, NULL, &req->obj);
- }
+
+ /* Stop the insanity before it turns "Hotel California" on us */
+ if (req->restarts >= cache_param->max_restarts)
+ wrk->handling = VCL_RET_DELIVER;
+
+ if (req->busyobj != NULL) {
+ req->req_step = R_STP_STREAM;
+ return (REQ_FSM_MORE);
+ }
+
+ if (wrk->handling == VCL_RET_RESTART) {
+ (void)HSH_Deref(&wrk->stats, NULL, &req->obj);
AZ(req->obj);
http_Teardown(req->resp);
req->req_step = R_STP_RESTART;
return (REQ_FSM_MORE);
- default:
- WRONG("Illegal action in vcl_deliver{}");
}
- req->req_step = R_STP_DELIVER;
- return (REQ_FSM_MORE);
-}
-
-/*--------------------------------------------------------------------
- * Deliver an already stored object
- *
-DOT subgraph xcluster_deliver {
-DOT deliver [
-DOT shape=record
-DOT label="{cnt_deliver:|Send body}"
-DOT ]
-DOT }
-DOT deliver -> DONE [style=bold,color=green]
-DOT deliver -> DONE [style=bold,color=red]
-DOT deliver -> DONE [style=bold,color=blue]
- *
- */
-
-static enum req_fsm_nxt
-cnt_deliver(struct worker *wrk, struct req *req)
-{
- struct busyobj *bo;
-
- CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
- CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
- CHECK_OBJ_NOTNULL(req->obj, OBJECT_MAGIC);
- bo = req->busyobj;
- CHECK_OBJ_ORNULL(bo, BUSYOBJ_MAGIC);
-
- if (bo != NULL) {
- while (bo->state < BOS_FAILED)
- (void)usleep(10000);
- assert(bo->state >= BOS_FAILED);
-
- if (bo->state == BOS_FAILED) {
- (void)HSH_Deref(&wrk->stats, NULL, &req->obj);
- VBO_DerefBusyObj(wrk, &req->busyobj);
- req->err_code = 503;
- req->req_step = R_STP_ERROR;
- return (REQ_FSM_MORE);
- }
- VBO_DerefBusyObj(wrk, &req->busyobj);
- }
-
- AZ(req->busyobj);
- req->director = NULL;
- req->restarts = 0;
+ assert(wrk->handling == VCL_RET_DELIVER);
RES_WriteObj(req);
@@ -240,6 +248,7 @@ cnt_deliver(struct worker *wrk, struct req *req)
http_Teardown(req->resp);
return (REQ_FSM_DONE);
}
+
/*--------------------------------------------------------------------
* Emit an error
*
@@ -249,7 +258,7 @@ DOT shape=record
DOT label="vcl_error()|resp."
DOT ]
DOT ERROR -> vcl_error
-DOT vcl_error-> prepresp [label=deliver]
+DOT vcl_error-> deliver [label=deliver]
DOT }
DOT vcl_error-> rsterr [label="restart",color=purple]
DOT rsterr [label="RESTART",shape=plaintext]
@@ -312,15 +321,16 @@ cnt_error(struct worker *wrk, struct req *req)
http_PutResponse(h, http_StatusMessage(req->err_code));
VCL_error_method(req->vcl, wrk, req, NULL, req->http->ws);
- if (wrk->handling == VCL_RET_RESTART &&
- req->restarts < cache_param->max_restarts) {
+ /* Stop the insanity before it turns "Hotel California" on us */
+ if (req->restarts >= cache_param->max_restarts)
+ wrk->handling = VCL_RET_DELIVER;
+
+ if (wrk->handling == VCL_RET_RESTART) {
HSH_Drop(wrk, &req->obj);
VBO_DerefBusyObj(wrk, &req->busyobj);
req->req_step = R_STP_RESTART;
return (REQ_FSM_MORE);
- } else if (wrk->handling == VCL_RET_RESTART)
- wrk->handling = VCL_RET_DELIVER;
-
+ }
/* We always close when we take this path */
req->doclose = SC_TX_ERROR;
@@ -331,7 +341,7 @@ cnt_error(struct worker *wrk, struct req *req)
req->err_reason = NULL;
http_Teardown(bo->bereq);
VBO_DerefBusyObj(wrk, &req->busyobj);
- req->req_step = R_STP_PREPRESP;
+ req->req_step = R_STP_DELIVER;
return (REQ_FSM_MORE);
}
@@ -344,8 +354,8 @@ DOT shape=record
DOT label="{cnt_fetch:|start fetch_thread}"
DOT ]
DOT }
-DOT fetch -> prepresp [style=bold,color=red]
-DOT fetch -> prepresp [style=bold,color=blue]
+DOT fetch -> deliver [style=bold,color=red]
+DOT fetch -> deliver [style=bold,color=blue]
*/
static enum req_fsm_nxt
@@ -373,7 +383,7 @@ cnt_fetch(struct worker *wrk, struct req *req)
req->obj = req->busyobj->fetch_obj;
VBO_DerefBusyObj(wrk, &req->busyobj);
assert(WRW_IsReleased(wrk));
- req->req_step = R_STP_PREPRESP;
+ req->req_step = R_STP_DELIVER;
}
return (REQ_FSM_MORE);
}
@@ -403,7 +413,7 @@ DOT lookup:eb:s -> lookup2 [style=bold,color=green]
DOT lookup:h:s -> lookup2 [style=bold,color=green]
DOT lookup2:pass:s -> pass [style=bold,color=red]
DOT lookup2:fetch:s -> miss [style=bold,color=blue]
-DOT lookup2:deliver:s -> prepresp:nw [style=bold,color=green]
+DOT lookup2:deliver:s -> deliver:n [style=bold,color=green]
*/
static enum req_fsm_nxt
@@ -496,7 +506,7 @@ cnt_lookup(struct worker *wrk, struct req *req)
(void)HTTP1_DiscardReqBody(req);// XXX: handle err
}
wrk->stats.cache_hit++;
- req->req_step = R_STP_PREPRESP;
+ req->req_step = R_STP_DELIVER;
return (REQ_FSM_MORE);
case VCL_RET_FETCH:
(void)HSH_Deref(&wrk->stats, NULL, &req->obj);
diff --git a/include/tbl/steps.h b/include/tbl/steps.h
index 6f219e4..30d331c 100644
--- a/include/tbl/steps.h
+++ b/include/tbl/steps.h
@@ -44,7 +44,7 @@ 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(prepresp, PREPRESP, (wrk, req))
+REQ_STEP(stream, STREAM, (wrk, req))
REQ_STEP(deliver, DELIVER, (wrk, req))
REQ_STEP(error, ERROR, (wrk, req))
#endif
More information about the varnish-commit
mailing list