Skip to content
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
10 changes: 5 additions & 5 deletions bin/varnishd/cache/cache_req_fsm.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@
REQ_STEP(fetch, FETCH, static) \
REQ_STEP(deliver, DELIVER, static) \
REQ_STEP(vclfail, VCLFAIL, static) \
REQ_STEP(synth, SYNTH, static) \
REQ_STEP(synth, SYNTH, ) \
REQ_STEP(transmit, TRANSMIT, static) \
REQ_STEP(finish, FINISH, static)

Expand Down Expand Up @@ -341,7 +341,7 @@ cnt_synth(struct worker *wrk, struct req *req)

VSLb_ts_req(req, "Process", W_TIM_real(wrk));

while (wrk->vpi->handling == VCL_RET_FAIL) {
while (req->req_reset || wrk->vpi->handling == VCL_RET_FAIL) {
if (req->esi_level > 0) {
wrk->vpi->handling = VCL_RET_DELIVER;
break;
Expand Down Expand Up @@ -596,9 +596,9 @@ cnt_lookup(struct worker *wrk, struct req *req)
if (lr == HSH_BUSY) {
/*
* We lost the session to a busy object, disembark the
* worker thread. We return to STP_LOOKUP when the busy
* object has been unbusied, and still have the objhead
* around to restart the lookup with.
* worker thread. We return to R_STP_LOOKUP, with the
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the commit message sounds like there would be more to it, but this is really just a comment fix?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this describes the old waiting list system with the retired hash_objhead field. I noticed this while surveying the req_reset behavior because we have more waiting list features on the Enterprise side (primarily #3835).

There was no reason to omit it from this patch series.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was really only asking because the commit message " req_fsm: Clear stale reference to req->hash_objhead" sounds like you had other intentions than only polishing a comment.

* object still around when it has been unbusied, to
* restart the lookup with.
*/
return (REQ_FSM_DISEMBARK);
}
Expand Down
1 change: 1 addition & 0 deletions bin/varnishd/cache/cache_varnishd.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ struct req_step {

extern const struct req_step R_STP_TRANSPORT[1];
extern const struct req_step R_STP_RECV[1];
extern const struct req_step R_STP_SYNTH[1];

struct vxid_pool {
uint64_t next;
Expand Down
21 changes: 14 additions & 7 deletions bin/varnishd/cache/cache_vrt_vcl.c
Original file line number Diff line number Diff line change
Expand Up @@ -560,13 +560,16 @@ req_poll(struct worker *wrk, struct req *req)
{
struct req *top;

/* NB: Since a fail transition leads to vcl_synth, the request may be
* short-circuited twice.
/* If the req_reset flag was raised without taking the emulated
* return(fail) transition, there must be a good reason for that.
* One is that sub vcl_recv is always followed by a call to sub
* vcl_hash to always compute a cache key. The other one is that
* we always want to run sub vcl_synth for return(fail) even if
* we won't deliver the response, and maybe sub vcl_synth needs
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not understand this. The only place where req_reset is set, VCL_RET_FAIL handling is signaled. Why does this pivot around req_reset and not VCL_RET_FAIL as already seems to be the case?

Also, is vcl_synth{} still the right place for this? Do we need some place to handle VCL_RET_FAIL, where it is clear that we do not emit headers?

I do not want to say that this is wrong, but could you please at least explain more?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The req_poll() function is a short-circuit to circumvent VCL execution once a request is "reset". For now, that is limited to aborted h2 connections or h2 streams being reset (and again, #3835 and more on the enterprise side).

The goal is to ensure that this short circuit either emulates a return (fail) that normally leads to vcl_synth (via R_STP_VCLFAIL) but does not prevent vcl_synth from being executed.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not understand how your response would answer my questions.

  • why does this (need to) look at req_reset and not just at VCL_RET_FAIL?

  • Would it not be cleaner to have a vcl sub to handle VCL_RET_FAIL rather than invoking vcl_synth {}, but without the intended effect? The existing code path in vcl_synth {} is to handle a return(fail) from vcl_synth {} itself, but now entering vcl_synth {} for fail paths and not executing the expected delivery seems plain wrong to me.

Side note: We should base our design decisions on what we have in our code base. What is in your private fork should not guide us.

* the cache key. There may be other good reasons to proceed.
*/
if (req->req_reset) {
wrk->vpi->handling = VCL_RET_FAIL;
return (-1);
}
if (req->req_reset)
return (0);

top = req->top->topreq;
CHECK_OBJ_NOTNULL(top, REQ_MAGIC);
Expand All @@ -581,8 +584,12 @@ req_poll(struct worker *wrk, struct req *req)

VSLb_ts_req(req, "Reset", W_TIM_real(wrk));
wrk->stats->req_reset++;
wrk->vpi->handling = VCL_RET_FAIL;
req->req_reset = 1;

if (req->req_step == R_STP_SYNTH)
return (0);

wrk->vpi->handling = VCL_RET_FAIL;
return (-1);
}

Expand Down
11 changes: 9 additions & 2 deletions bin/varnishtest/tests/t02025.vtc
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ varnish v1 -vcl {
sub vcl_miss {
vtc.panic("unreachable");
}

sub vcl_synth {
if (resp.status == 408) {
set resp.http.gone = "bye";
}
}
} -start

logexpect l1 -v v1 -g raw -i Debug {
Expand Down Expand Up @@ -51,7 +57,8 @@ varnish v1 -expect req_reset == 1
# is interpreted as before a second elapsed. Session VXIDs showing up
# numerous times become increasingly more suspicious. The format can of
# course be extended to add anything else useful for data mining.
shell -expect "1000 ${localhost} 408" {
shell -expect "1000 ${localhost} 408 bye" {
varnishncsa -n ${v1_name} -d \
-q 'Timestamp:Reset[2] < 1.0' -F '%{VSL:Begin[2]}x %h %s'
-q 'Timestamp:Reset[2] < 1.0' \
-F '%{VSL:Begin[2]}x %h %s %{gone}o'
}