Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Partial support for Cache-Control's no-cache directive #4073

Open
wants to merge 17 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions bin/varnishd/cache/cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,7 @@ struct objcore {
uint16_t oa_present;

unsigned timer_idx; // XXX 4Gobj limit
unsigned waitinglist_gen;
vtim_real last_lru;
VTAILQ_ENTRY(objcore) hsh_list;
VTAILQ_ENTRY(objcore) lru_list;
Expand Down Expand Up @@ -471,6 +472,7 @@ struct req {
stream_close_t doclose;
unsigned restarts;
unsigned esi_level;
unsigned waitinglist_gen;

/* Delivery mode */
unsigned res_mode;
Expand All @@ -497,9 +499,6 @@ struct req {

struct objcore *body_oc;

/* The busy objhead we sleep on */
struct objhead *hash_objhead;

/* Built Vary string == workspace reservation */
uint8_t *vary_b;
uint8_t *vary_e;
Expand Down
2 changes: 1 addition & 1 deletion bin/varnishd/cache/cache_ban_lurker.c
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,7 @@ ban_lurker_test_ban(struct worker *wrk, struct ban *bt,
if (i)
ObjSendEvent(wrk, oc, OEV_BANCHG);
}
(void)HSH_DerefObjCore(wrk, &oc, 0);
(void)HSH_DerefObjCore(wrk, &oc);
}
}

Expand Down
34 changes: 32 additions & 2 deletions bin/varnishd/cache/cache_busyobj.c
Original file line number Diff line number Diff line change
Expand Up @@ -179,8 +179,7 @@ VBO_ReleaseBusyObj(struct worker *wrk, struct busyobj **pbo)
wrk->stats->ws_backend_overflow++;

if (bo->fetch_objcore != NULL) {
(void)HSH_DerefObjCore(wrk, &bo->fetch_objcore,
HSH_RUSH_POLICY);
(void)HSH_DerefObjCore(wrk, &bo->fetch_objcore);
}

VRT_Assign_Backend(&bo->director_req, NULL);
Expand All @@ -195,3 +194,34 @@ VBO_ReleaseBusyObj(struct worker *wrk, struct busyobj **pbo)

vbo_Free(&bo);
}

void
VBO_SetState(struct worker *wrk, struct busyobj *bo, enum boc_state_e next)
{
unsigned broadcast;

CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);

switch (next) {
case BOS_REQ_DONE:
AN(bo->req);
broadcast = bo->is_bgfetch;
break;
case BOS_STREAM:
if (!bo->do_stream) {
bo->req = NULL;
return; /* keep objcore busy */
}
/* fall through */
case BOS_FINISHED:
case BOS_FAILED:
broadcast = 1;
break;
default:
WRONG("unexpected BOC state");
}

bo->req = NULL;
ObjSetState(wrk, bo->fetch_objcore, next, broadcast);
}
6 changes: 3 additions & 3 deletions bin/varnishd/cache/cache_expire.c
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ EXP_Insert(struct worker *wrk, struct objcore *oc)
ObjSendEvent(wrk, oc, OEV_EXPIRE);
tmpoc = oc;
assert(oc->refcnt >= 2); /* Silence coverity */
(void)HSH_DerefObjCore(wrk, &oc, 0);
(void)HSH_DerefObjCore(wrk, &oc);
AZ(oc);
assert(tmpoc->refcnt >= 1); /* Silence coverity */
}
Expand Down Expand Up @@ -309,7 +309,7 @@ exp_inbox(struct exp_priv *ep, struct objcore *oc, unsigned flags, double now)
VXID(ObjGetXID(ep->wrk, oc)), EXP_Ttl(NULL, oc) - now,
(intmax_t)oc->hits);
ObjSendEvent(ep->wrk, oc, OEV_EXPIRE);
(void)HSH_DerefObjCore(ep->wrk, &oc, 0);
(void)HSH_DerefObjCore(ep->wrk, &oc);
return;
}

Expand Down Expand Up @@ -387,7 +387,7 @@ exp_expire(struct exp_priv *ep, vtim_real now)
VXID(ObjGetXID(ep->wrk, oc)), EXP_Ttl(NULL, oc) - now,
(intmax_t)oc->hits);
ObjSendEvent(ep->wrk, oc, OEV_EXPIRE);
(void)HSH_DerefObjCore(ep->wrk, &oc, 0);
(void)HSH_DerefObjCore(ep->wrk, &oc);
}
return (0);
}
Expand Down
87 changes: 26 additions & 61 deletions bin/varnishd/cache/cache_fetch.c
Original file line number Diff line number Diff line change
Expand Up @@ -289,14 +289,12 @@ vbf_stp_mkbereq(struct worker *wrk, struct busyobj *bo)
HTTP_Clone(bo->bereq, bo->bereq0);

if (bo->req->req_body_status->avail == 0) {
bo->req = NULL;
ObjSetState(bo->wrk, oc, BOS_REQ_DONE);
VBO_SetState(bo->wrk, bo, BOS_REQ_DONE);
} else if (bo->req->req_body_status == BS_CACHED) {
AN(bo->req->body_oc);
bo->bereq_body = bo->req->body_oc;
HSH_Ref(bo->bereq_body);
bo->req = NULL;
ObjSetState(bo->wrk, oc, BOS_REQ_DONE);
VBO_SetState(bo->wrk, bo, BOS_REQ_DONE);
}
return (F_STP_STARTFETCH);
}
Expand Down Expand Up @@ -538,10 +536,8 @@ vbf_stp_startfetch(struct worker *wrk, struct busyobj *bo)

VSLb_ts_busyobj(bo, "Process", W_TIM_real(wrk));
assert(oc->boc->state <= BOS_REQ_DONE);
if (oc->boc->state != BOS_REQ_DONE) {
bo->req = NULL;
ObjSetState(wrk, oc, BOS_REQ_DONE);
}
if (oc->boc->state != BOS_REQ_DONE)
VBO_SetState(wrk, bo, BOS_REQ_DONE);

if (bo->do_esi)
bo->do_stream = 0;
Expand Down Expand Up @@ -706,11 +702,7 @@ vbf_stp_fetch(struct worker *wrk, struct busyobj *bo)

assert(oc->boc->state == BOS_REQ_DONE);

if (bo->do_stream) {
ObjSetState(wrk, oc, BOS_PREP_STREAM);
HSH_Unbusy(wrk, oc);
ObjSetState(wrk, oc, BOS_STREAM);
}
VBO_SetState(wrk, bo, BOS_STREAM);

VSLb(bo->vsl, SLT_Fetch_Body, "%u %s %s",
bo->htc->body_status->nbr, bo->htc->body_status->name,
Expand Down Expand Up @@ -745,13 +737,10 @@ vbf_stp_fetchend(struct worker *wrk, struct busyobj *bo)

if (bo->do_stream)
assert(oc->boc->state == BOS_STREAM);
else {
else
assert(oc->boc->state == BOS_REQ_DONE);
ObjSetState(wrk, oc, BOS_PREP_STREAM);
HSH_Unbusy(wrk, oc);
}

ObjSetState(wrk, oc, BOS_FINISHED);
VBO_SetState(wrk, bo, BOS_FINISHED);
VSLb_ts_busyobj(bo, "BerespBody", W_TIM_real(wrk));
if (bo->stale_oc != NULL) {
VSL(SLT_ExpKill, NO_VXID, "VBF_Superseded x=%ju n=%ju",
Expand Down Expand Up @@ -878,11 +867,7 @@ vbf_stp_condfetch(struct worker *wrk, struct busyobj *bo)
ObjSetFlag(bo->wrk, oc, OF_IMSCAND, 0);
AZ(ObjCopyAttr(bo->wrk, oc, stale_oc, OA_GZIPBITS));

if (bo->do_stream) {
ObjSetState(wrk, oc, BOS_PREP_STREAM);
HSH_Unbusy(wrk, oc);
ObjSetState(wrk, oc, BOS_STREAM);
}
VBO_SetState(wrk, bo, BOS_STREAM);

INIT_OBJ(vop, VBF_OBITER_PRIV_MAGIC);
vop->bo = bo;
Expand All @@ -903,9 +888,7 @@ vbf_stp_condfetch(struct worker *wrk, struct busyobj *bo)
*
* replaces a stale object unless
* - abandoning the bereq or
* - leaving vcl_backend_error with return (deliver) and beresp.ttl == 0s or
* - there is a waitinglist on this object because in this case the default ttl
* would be 1s, so we might be looking at the same case as the previous
* - leaving vcl_backend_error with return (deliver)
*
* We do want the stale replacement to avoid an object pileup with short ttl and
* long grace/keep, yet there could exist cases where a cache object is
Expand All @@ -928,7 +911,8 @@ vbf_stp_error(struct worker *wrk, struct busyobj *bo)
CHECK_OBJ_NOTNULL(bo, BUSYOBJ_MAGIC);
oc = bo->fetch_objcore;
CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
AN(oc->flags & OC_F_BUSY);
CHECK_OBJ_NOTNULL(oc->boc, BOC_MAGIC);
assert(oc->boc->state < BOS_STREAM);
assert(bo->director_state == DIR_S_NULL);

if (wrk->vpi->handling != VCL_RET_ERROR)
Expand Down Expand Up @@ -960,23 +944,9 @@ vbf_stp_error(struct worker *wrk, struct busyobj *bo)

stale = bo->stale_oc;
oc->t_origin = now;
if (!VTAILQ_EMPTY(&oc->objhead->waitinglist)) {
/*
* If there is a waitinglist, it means that there is no
* grace-able object, so cache the error return for a
* short time, so the waiting list can drain, rather than
* each objcore on the waiting list sequentially attempt
* to fetch from the backend.
*/
oc->ttl = 1;
oc->grace = 5;
oc->keep = 5;
stale = NULL;
} else {
oc->ttl = 0;
oc->grace = 0;
oc->keep = 0;
}
oc->ttl = 0;
oc->grace = 0;
oc->keep = 0;

synth_body = VSB_new_auto();
AN(synth_body);
Expand Down Expand Up @@ -1026,11 +996,10 @@ vbf_stp_error(struct worker *wrk, struct busyobj *bo)
}
AZ(ObjSetU64(wrk, oc, OA_LEN, o));
VSB_destroy(&synth_body);
ObjSetState(wrk, oc, BOS_PREP_STREAM);
HSH_Unbusy(wrk, oc);
VBO_SetState(wrk, bo, BOS_STREAM);
if (stale != NULL && oc->ttl > 0)
HSH_Kill(stale);
ObjSetState(wrk, oc, BOS_FINISHED);
VBO_SetState(wrk, bo, BOS_FINISHED);
return (F_STP_DONE);
}

Expand All @@ -1048,10 +1017,8 @@ vbf_stp_fail(struct worker *wrk, struct busyobj *bo)
CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);

assert(oc->boc->state < BOS_FINISHED);
HSH_Fail(oc);
if (!(oc->flags & OC_F_BUSY))
HSH_Kill(oc);
ObjSetState(wrk, oc, BOS_FAILED);
VBO_SetState(wrk, bo, BOS_FAILED);
HSH_Kill(oc);
return (F_STP_DONE);
}

Expand Down Expand Up @@ -1123,7 +1090,7 @@ vbf_fetch_thread(struct worker *wrk, void *priv)
http_Teardown(bo->beresp);
// cannot make assumptions about the number of references here #3434
if (bo->bereq_body != NULL)
(void) HSH_DerefObjCore(bo->wrk, &bo->bereq_body, 0);
(void)HSH_DerefObjCore(bo->wrk, &bo->bereq_body);

if (oc->boc->state == BOS_FINISHED) {
AZ(oc->flags & OC_F_FAILED);
Expand All @@ -1133,7 +1100,7 @@ vbf_fetch_thread(struct worker *wrk, void *priv)
// AZ(oc->boc); // XXX

if (bo->stale_oc != NULL)
(void)HSH_DerefObjCore(wrk, &bo->stale_oc, 0);
(void)HSH_DerefObjCore(wrk, &bo->stale_oc);

wrk->vsl = NULL;
HSH_DerefBoc(wrk, oc);
Expand All @@ -1157,7 +1124,6 @@ VBF_Fetch(struct worker *wrk, struct req *req, struct objcore *oc,
CHECK_OBJ_NOTNULL(wrk, WORKER_MAGIC);
CHECK_OBJ_NOTNULL(req, REQ_MAGIC);
CHECK_OBJ_NOTNULL(oc, OBJCORE_MAGIC);
AN(oc->flags & OC_F_BUSY);
CHECK_OBJ_ORNULL(oldoc, OBJCORE_MAGIC);

bo = VBO_GetBusyObj(wrk, req);
Expand All @@ -1166,6 +1132,7 @@ VBF_Fetch(struct worker *wrk, struct req *req, struct objcore *oc,

boc = HSH_RefBoc(oc);
CHECK_OBJ_NOTNULL(boc, BOC_MAGIC);
assert(boc->state < BOS_STREAM);

switch (mode) {
case VBF_PASS:
Expand Down Expand Up @@ -1224,7 +1191,7 @@ VBF_Fetch(struct worker *wrk, struct req *req, struct objcore *oc,
"No thread available for bgfetch");
(void)vbf_stp_fail(req->wrk, bo);
if (bo->stale_oc != NULL)
(void)HSH_DerefObjCore(wrk, &bo->stale_oc, 0);
(void)HSH_DerefObjCore(wrk, &bo->stale_oc);
HSH_DerefBoc(wrk, oc);
SES_Rel(bo->sp);
THR_SetBusyobj(NULL);
Expand All @@ -1237,17 +1204,15 @@ VBF_Fetch(struct worker *wrk, struct req *req, struct objcore *oc,
(void)VRB_Ignore(req);
} else {
ObjWaitState(oc, BOS_STREAM);
if (oc->boc->state == BOS_FAILED) {
AN((oc->flags & OC_F_FAILED));
} else {
AZ(oc->flags & OC_F_BUSY);
}
AZ(oc->flags & OC_F_BUSY);
if (oc->boc->state == BOS_FAILED)
AN(oc->flags & OC_F_FAILED);
}
}
AZ(bo);
VSLb_ts_req(req, "Fetch", W_TIM_real(wrk));
assert(oc->boc == boc);
HSH_DerefBoc(wrk, oc);
if (mode == VBF_BACKGROUND)
(void)HSH_DerefObjCore(wrk, &oc, HSH_RUSH_POLICY);
(void)HSH_DerefObjCore(wrk, &oc);
}
Loading
Loading