From fb588fa2d0e4449f9ead8a4858f9407f7a258722 Mon Sep 17 00:00:00 2001 From: phk Date: Sun, 30 Sep 2007 20:57:30 +0000 Subject: [PATCH] Add the first stab at a "restart" mechanism. The intent is to be able to do things like: backend b1 { set backend.host = "fs.freebsd.dk"; set backend.port = "82"; } backend b2 { set backend.host = "fs.freebsd.dk"; set backend.port = "81"; } backend b3 { set backend.host = "fs.freebsd.dk"; set backend.port = "80"; } sub vcl_recv { remove req.http.cookie; if (req.restarts == 0) { set req.backend = b1; } else if (req.restarts == 1) { set req.backend = b2; } else { set req.backend = b3; } } sub vcl_fetch { if (obj.status != 200) { restart; } } git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@2067 d4fa192b-c00b-0410-8231-f00ffab90ce4 --- varnish-cache/bin/varnishd/cache.h | 2 + varnish-cache/bin/varnishd/cache_center.c | 71 +++++++++++++---------- varnish-cache/bin/varnishd/cache_hash.c | 2 +- varnish-cache/bin/varnishd/cache_vrt.c | 13 +++++ 4 files changed, 57 insertions(+), 31 deletions(-) diff --git a/varnish-cache/bin/varnishd/cache.h b/varnish-cache/bin/varnishd/cache.h index 90f342f7..be8ab595 100644 --- a/varnish-cache/bin/varnishd/cache.h +++ b/varnish-cache/bin/varnishd/cache.h @@ -278,6 +278,8 @@ struct sess { int id; unsigned xid; + int restarts; + struct worker *wrk; socklen_t sockaddrlen; diff --git a/varnish-cache/bin/varnishd/cache_center.c b/varnish-cache/bin/varnishd/cache_center.c index 127a6b44..ac773a07 100644 --- a/varnish-cache/bin/varnishd/cache_center.c +++ b/varnish-cache/bin/varnishd/cache_center.c @@ -303,21 +303,30 @@ cnt_fetch(struct sess *sp) VBE_free_bereq(sp->bereq); sp->bereq = NULL; - if (i) { + if (0 && i) { SYN_ErrorPage(sp, 503, "Error talking to backend", 30); } else { - RFC2616_cache_policy(sp, &sp->obj->http); /* XXX -> VCL */ + if (!i) + RFC2616_cache_policy(sp, &sp->obj->http); /* XXX -> VCL */ + else + sp->obj->http.status = 503; VCL_fetch_method(sp); switch (sp->handling) { case VCL_RET_ERROR: + case VCL_RET_RESTART: sp->obj->ttl = 0; sp->obj->cacheable = 0; HSH_Unbusy(sp->obj); HSH_Deref(sp->obj); sp->obj = NULL; - sp->step = STP_ERROR; + if (sp->handling == VCL_RET_ERROR) + sp->step = STP_ERROR; + else { + sp->restarts++; + sp->step = STP_RECV; + } return (0); case VCL_RET_PASS: sp->obj->pass = 1; @@ -696,40 +705,42 @@ cnt_recv(struct sess *sp) { int done; - AZ(sp->vcl); AZ(sp->obj); - /* Update stats of various sorts */ - VSL_stats->client_req++; /* XXX not locked */ - sp->t_req = TIM_real(); - sp->wrk->used = sp->t_req; - sp->wrk->acct.req++; + if (sp->restarts == 0) { + AZ(sp->vcl); + /* Update stats of various sorts */ + VSL_stats->client_req++; /* XXX not locked */ + sp->t_req = TIM_real(); + sp->wrk->used = sp->t_req; + sp->wrk->acct.req++; + + /* Assign XID and log */ + sp->xid = ++xids; /* XXX not locked */ + WSP(sp, SLT_ReqStart, "%s %s %u", sp->addr, sp->port, sp->xid); + + /* Borrow VCL reference from worker thread */ + VCL_Refresh(&sp->wrk->vcl); + sp->vcl = sp->wrk->vcl; + sp->wrk->vcl = NULL; + + done = http_DissectRequest(sp); + if (done != 0) { + RES_Error(sp, done, NULL); /* XXX: STP_ERROR ? */ + sp->step = STP_DONE; + return (0); + } - /* Assign XID and log */ - sp->xid = ++xids; /* XXX not locked */ - WSP(sp, SLT_ReqStart, "%s %s %u", sp->addr, sp->port, sp->xid); + sp->doclose = http_DoConnection(sp->http); - /* Borrow VCL reference from worker thread */ - VCL_Refresh(&sp->wrk->vcl); - sp->vcl = sp->wrk->vcl; - sp->wrk->vcl = NULL; + /* By default we use the first backend */ + AZ(sp->backend); + sp->backend = sp->vcl->backend[0]; + CHECK_OBJ_NOTNULL(sp->backend, BACKEND_MAGIC); - done = http_DissectRequest(sp); - if (done != 0) { - RES_Error(sp, done, NULL); /* XXX: STP_ERROR ? */ - sp->step = STP_DONE; - return (0); + /* XXX: Handle TRACE & OPTIONS of Max-Forwards = 0 */ } - sp->doclose = http_DoConnection(sp->http); - - /* By default we use the first backend */ - AZ(sp->backend); - sp->backend = sp->vcl->backend[0]; - CHECK_OBJ_NOTNULL(sp->backend, BACKEND_MAGIC); - - /* XXX: Handle TRACE & OPTIONS of Max-Forwards = 0 */ - VCL_recv_method(sp); sp->wantbody = (strcmp(sp->http->hd[HTTP_HDR_REQ].b, "HEAD") != 0); diff --git a/varnish-cache/bin/varnishd/cache_hash.c b/varnish-cache/bin/varnishd/cache_hash.c index ac89e290..66d3b073 100644 --- a/varnish-cache/bin/varnishd/cache_hash.c +++ b/varnish-cache/bin/varnishd/cache_hash.c @@ -304,7 +304,7 @@ HSH_Deref(struct object *o) if (r != 0) return; - if (o->http.ws->s != NULL) + if (o->http.ws != NULL && o->http.ws->s != NULL) free(o->http.ws->s); if (o->vary != NULL) diff --git a/varnish-cache/bin/varnishd/cache_vrt.c b/varnish-cache/bin/varnishd/cache_vrt.c index 908e296d..23f55111 100644 --- a/varnish-cache/bin/varnishd/cache_vrt.c +++ b/varnish-cache/bin/varnishd/cache_vrt.c @@ -239,6 +239,9 @@ VRT_r_obj_status(const struct sess *sp) { CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); CHECK_OBJ_NOTNULL(sp->obj, OBJECT_MAGIC); + /* XXX: use http_GetStatus() */ + if (sp->obj->http.status) + return (sp->obj->http.status); return (atoi(sp->obj->http.hd[HTTP_HDR_STATUS].b)); } @@ -356,6 +359,16 @@ VREQ(proto, HTTP_HDR_PROTO) /*--------------------------------------------------------------------*/ +int +VRT_r_req_restarts(const struct sess *sp) +{ + + CHECK_OBJ_NOTNULL(sp, SESS_MAGIC); + return (sp->restarts); +} + +/*--------------------------------------------------------------------*/ + const char * VRT_r_resp_proto(const struct sess *sp) { -- 2.39.5