Skip to content

Commit c461fb2

Browse files
committed
condfetch: Demote to fetch for dying stale_oc
When it is time to decide between making a bereq for a regular or conditional fetch, we need to ensure that the stale object is still valid. There is a window between the lookup and the begining of a fetch task during which the object could have been invalidated. The window is in theory much smaller than the one between the lookup and the processing of a 304 response, but it can be significant if the fetch task was queued or restarted. Catching it early allows to proceed with a regular fetch.
1 parent 588d103 commit c461fb2

File tree

2 files changed

+60
-1
lines changed

2 files changed

+60
-1
lines changed

bin/varnishd/cache/cache_fetch.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ vbf_stp_mkbereq(struct worker *wrk, struct busyobj *bo)
270270
}
271271
http_ForceField(bo->bereq0, HTTP_HDR_PROTO, "HTTP/1.1");
272272

273-
if (bo->stale_oc != NULL &&
273+
if (bo->stale_oc != NULL && !(bo->stale_oc->flags & OC_F_DYING) &&
274274
ObjCheckFlag(bo->wrk, bo->stale_oc, OF_IMSCAND) &&
275275
(bo->stale_oc->boc != NULL || ObjGetLen(wrk, bo->stale_oc) != 0)) {
276276
AZ(bo->stale_oc->flags & (OC_F_HFM|OC_F_PRIVATE));

bin/varnishtest/tests/c00130.vtc

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
varnishtest "Demote condfetch to fetch on invalidated stale object"
2+
3+
barrier b1 sock 2
4+
barrier b2 sock 2
5+
6+
server s1 {
7+
rxreq
8+
txresp -hdr {ETag: "foo"} -body corrupted
9+
10+
rxreq
11+
expect req.http.If-None-Match == <undef>
12+
txresp -hdr {ETag: "foo"} -body valid
13+
} -start
14+
15+
varnish v1 -vcl+backend {
16+
import vtc;
17+
sub vcl_recv {
18+
if (req.method == "PURGE") {
19+
return (purge);
20+
}
21+
}
22+
sub vcl_miss {
23+
if (req.http.sync) {
24+
vtc.barrier_sync("${b1_sock}");
25+
vtc.barrier_sync("${b2_sock}");
26+
}
27+
}
28+
sub vcl_backend_response {
29+
set beresp.ttl = 1ms;
30+
set beresp.grace = 0s;
31+
set beresp.keep = 10s;
32+
}
33+
sub vcl_deliver {
34+
set resp.http.obj-hits = obj.hits;
35+
}
36+
} -start
37+
38+
client c1 {
39+
txreq
40+
rxresp
41+
expect resp.body == corrupted
42+
expect resp.http.obj-hits == 0
43+
44+
delay 0.1
45+
46+
txreq -hdr "sync: true"
47+
rxresp
48+
expect resp.body == valid
49+
expect resp.http.obj-hits == 0
50+
} -start
51+
52+
barrier b1 sync
53+
client c2 {
54+
txreq -req PURGE
55+
rxresp
56+
} -run
57+
barrier b2 sync
58+
59+
client c1 -wait

0 commit comments

Comments
 (0)