Skip to content
This repository was archived by the owner on Feb 16, 2026. It is now read-only.

Commit 8aaeced

Browse files
committed
fetch: Retire waiting list safety net
If a synthetic beresp is inserted into the cache with no TTL, grace or keep at all, it is now considered validated (although not in the best circumstances) and will be passed to all requests in the waiting list.
1 parent 11c2676 commit 8aaeced

3 files changed

Lines changed: 83 additions & 33 deletions

File tree

bin/varnishd/cache/cache_fetch.c

Lines changed: 4 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -896,9 +896,7 @@ vbf_stp_condfetch(struct worker *wrk, struct busyobj *bo)
896896
*
897897
* replaces a stale object unless
898898
* - abandoning the bereq or
899-
* - leaving vcl_backend_error with return (deliver) and beresp.ttl == 0s or
900-
* - there is a waitinglist on this object because in this case the default ttl
901-
* would be 1s, so we might be looking at the same case as the previous
899+
* - leaving vcl_backend_error with return (deliver)
902900
*
903901
* We do want the stale replacement to avoid an object pileup with short ttl and
904902
* long grace/keep, yet there could exist cases where a cache object is
@@ -954,23 +952,9 @@ vbf_stp_error(struct worker *wrk, struct busyobj *bo)
954952

955953
stale = bo->stale_oc;
956954
oc->t_origin = now;
957-
if (!VTAILQ_EMPTY(&oc->objhead->waitinglist)) {
958-
/*
959-
* If there is a waitinglist, it means that there is no
960-
* grace-able object, so cache the error return for a
961-
* short time, so the waiting list can drain, rather than
962-
* each objcore on the waiting list sequentially attempt
963-
* to fetch from the backend.
964-
*/
965-
oc->ttl = 1;
966-
oc->grace = 5;
967-
oc->keep = 5;
968-
stale = NULL;
969-
} else {
970-
oc->ttl = 0;
971-
oc->grace = 0;
972-
oc->keep = 0;
973-
}
955+
oc->ttl = 0;
956+
oc->grace = 0;
957+
oc->keep = 0;
974958

975959
synth_body = VSB_new_auto();
976960
AN(synth_body);

bin/varnishtest/tests/c00131.vtc

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
varnishtest "waiting list rush from vcl_backend_error"
2+
3+
barrier b1 sock 2
4+
barrier b2 sock 2
5+
6+
server s1 {
7+
rxreq
8+
send garbage
9+
} -start
10+
11+
varnish v1 -cliok "param.set debug +syncvsl,+waitinglist"
12+
varnish v1 -vcl+backend {
13+
import vtc;
14+
sub vcl_backend_fetch {
15+
vtc.barrier_sync("${b1_sock}");
16+
vtc.barrier_sync("${b2_sock}");
17+
}
18+
sub vcl_backend_error {
19+
set beresp.http.error-vxid = bereq.xid;
20+
}
21+
} -start
22+
23+
client c1 {
24+
txreq
25+
rxresp
26+
expect resp.http.error-vxid == 1002
27+
} -start
28+
29+
barrier b1 sync
30+
31+
logexpect l1 -v v1 -q Debug -g raw {
32+
loop 4 {
33+
expect * * Debug "on waiting list"
34+
}
35+
} -start
36+
37+
client c2 {
38+
txreq
39+
rxresp
40+
expect resp.http.error-vxid == 1002
41+
} -start
42+
43+
client c3 {
44+
txreq
45+
rxresp
46+
expect resp.http.error-vxid == 1002
47+
} -start
48+
49+
client c4 {
50+
txreq
51+
rxresp
52+
expect resp.http.error-vxid == 1002
53+
} -start
54+
55+
client c5 {
56+
txreq
57+
rxresp
58+
expect resp.http.error-vxid == 1002
59+
} -start
60+
61+
logexpect l1 -wait
62+
63+
barrier b2 sync
64+
65+
client c1 -wait
66+
client c2 -wait
67+
client c3 -wait
68+
client c4 -wait
69+
client c5 -wait
70+
71+
varnish v1 -expect n_expired == 1

doc/sphinx/reference/vcl_step.rst

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -378,19 +378,14 @@ This subroutine is called if we fail the backend fetch or if
378378

379379
Returning with :ref:`abandon` does not leave a cache object.
380380

381-
If returning with ``deliver`` and a ``beresp.ttl > 0s``, a synthetic
382-
cache object is generated in VCL, whose body may be constructed using
383-
the ``synthetic()`` function.
384-
385-
When there is a waiting list on the object, the default ``ttl`` will
386-
be positive (currently one second), set before entering
387-
``vcl_backend_error``. This is to avoid request serialization and
388-
hammering on a potentially failing backend.
389-
390-
Since these synthetic objects are cached in these special
391-
circumstances, be cautious with putting private information there. If
392-
you really must, then you need to explicitly set ``beresp.ttl`` to
393-
zero in ``vcl_backend_error``.
381+
If returning with ``deliver`` and ``beresp.uncacheable == false``, a
382+
synthetic cache object is generated in VCL, whose body may be constructed
383+
using the ``synthetic()`` function.
384+
385+
Since these synthetic objects are cached in these special circumstances,
386+
be cautious with putting private information there. If you really must,
387+
then you need to explicitly set ``beresp.uncacheable`` to ``true`` in
388+
``vcl_backend_error``.
394389

395390
The `vcl_backend_error` subroutine may terminate with calling ``return()``
396391
with one of the following keywords:

0 commit comments

Comments
 (0)