Commit e676f779 authored by AlveElde's avatar AlveElde Committed by Nils Goroll

purge: Use EXP_Reduce() instead of EXP_Rearm()

When a stale object is soft-purged, the time until the object expires
should not be reset, as repeated soft-purges could keep the object
around indefinitely.
parent 9c0abf0c
......@@ -747,7 +747,7 @@ HSH_Purge(struct worker *wrk, struct objhead *oh, vtim_real ttl_now,
if (is_purge)
EXP_Remove(ocp[i], NULL);
else
EXP_Rearm(ocp[i], ttl_now, ttl, grace, keep);
EXP_Reduce(ocp[i], ttl_now, ttl, grace, keep);
(void)HSH_DerefObjCore(wrk, &ocp[i], 0);
AZ(ocp[i]);
total++;
......
varnishtest "Softpurging a stale object"
server s1 {
rxreq
txresp -hdr "version: 1"
rxreq
txresp -hdr "version: 2"
} -start
varnish v1 -vcl+backend {
import purge;
sub vcl_hit {
if (req.http.purge) {
set req.http.npurged = purge.soft();
return (synth(200));
}
}
sub vcl_backend_response {
set beresp.grace = 3s;
set beresp.keep = 10s;
}
sub vcl_synth {
set resp.http.npurged = req.http.npurged;
}
} -start
client c1 {
txreq
rxresp
expect resp.status == 200
expect resp.http.version == "1"
# Softpurge the object
txreq -hdr "purge: yes"
rxresp
expect resp.status == 200
expect resp.http.npurged == 1
# Wait for half the grace period
delay 1.5
# Softpurge the object again, this should not reset the expiry timer
txreq -hdr "purge: yes"
rxresp
expect resp.status == 200
expect resp.http.npurged == 1
# Wait for the object to enter keep
delay 1.5
# A grace hit should not be possible now
txreq
rxresp
expect resp.http.version == "2"
expect resp.status == 200
} -run
varnishtest "Softpurging an object cannot increase grace or keep"
server s1 {
rxreq
txresp -hdr "Last-Modified: Wed, 11 Sep 2013 13:36:55 GMT" -body "foo"
rxreq
expect req.http.if-modified-since == "Wed, 11 Sep 2013 13:36:55 GMT"
txresp -body "bar"
} -start
varnish v1 -arg "-p vsl_mask=+ExpKill" -vcl+backend {
import purge;
import std;
sub vcl_hit {
if (req.http.purge) {
set req.http.npurged = purge.soft(
grace = std.duration(req.http.grace, -1s),
keep = std.duration(req.http.keep, -1s));
return (synth(200));
}
}
sub vcl_backend_response {
set beresp.ttl = 1y;
set beresp.grace = 1y;
set beresp.keep = 1y;
}
sub vcl_synth {
set resp.http.npurged = req.http.npurged;
}
} -start
client c1 {
txreq
rxresp
expect resp.status == 200
expect resp.body == "foo"
# Reduce the objects grace
txreq -hdr "purge: yes" -hdr "grace: 10s"
rxresp
expect resp.status == 200
expect resp.http.npurged == 1
# Reduce the objects keep
txreq -hdr "purge: yes" -hdr "keep: 10s"
rxresp
expect resp.status == 200
expect resp.http.npurged == 1
# Reduce the objects grace and keep
txreq -hdr "purge: yes" -hdr "grace: 1s" -hdr "keep: 5s"
rxresp
expect resp.status == 200
expect resp.http.npurged == 1
# Increasing the objects grace is not possible
txreq -hdr "purge: yes" -hdr "grace: 15s"
rxresp
expect resp.status == 200
expect resp.http.npurged == 1
# Increasing the objects keep is not possible
txreq -hdr "purge: yes" -hdr "keep: 105"
rxresp
expect resp.status == 200
expect resp.http.npurged == 1
# Increasing the objects grace and keep is not possible
txreq -hdr "purge: yes" -hdr "grace: 15s" -hdr "keep: 15s"
rxresp
expect resp.status == 200
expect resp.http.npurged == 1
# Wait for the obejct to enter keep
delay 1
# We don't get a grace hit, but the backend gets an IMS header
txreq
rxresp
expect resp.status == 200
expect resp.body == "bar"
} -run
......@@ -98,12 +98,46 @@ $Restrict vcl_hit vcl_miss
$Function INT soft(DURATION ttl = 0, DURATION grace = -1, DURATION keep = -1)
Sets the *ttl*, *grace* and *keep*.
By default, *ttl* is set to 0 with *grace* and *keep* periods left
untouched. Setting a negative value for *grace* or *keep* periods
leaves them untouched. Setting all three parameters to ``0`` is
equivalent to a hard purge. It returns the number of soft-purged objects.
Sets the *ttl*, *grace* and *keep*. By default, *ttl* is set to ``0`` with
*grace* and *keep* periods left untouched. Setting *grace* or *keep* to a
negative value or to something higher than the objects current value leaves them
untouched. Setting all three parameters to ``0`` is equivalent to a hard purge.
Returns the number of soft-purged objects.
A soft-purge can only decrease the lifetime of an object. Let's consider an
object in cache created with *ttl*, *grace*, and *keep* of 60 seconds each:
``purge.soft(ttl = 0s, grace = -1s, keep = -1s);``
* If the object is **fresh**, the *ttl* is reduced to 0 seconds and the object
expires after 120 seconds.
* If the object is **stale**, the expiry time is not changed.
``purge.soft(ttl = 0s, grace = 10s, keep = 10s);``
* If the object is **fresh**, the *ttl* is reduced to 0 seconds, *grace* and
*keep* are reduced to 10 seconds. The object expires after 20 seconds.
* If the object has been **stale** for 5 seconds, *grace* is reduced to 5
seconds and *keep* is reduced to 10 seconds. The object expires after 15
seconds.
* If the object has been **stale** for 15 seconds, *grace* is reduced to 0
seconds and *keep* is reduced to 5 seconds. The object expires after 5
seconds.
* If the object has been **stale** for 20 seconds or more, the object
immediately expires.
``purge.soft(ttl = 10s, grace = -1s, keep = -1s);``
* If the object has been **fresh** for 5 seconds, the *ttl* is reduced to 10
seconds. The object expires after 130 seconds.
* If the object has been **fresh** for 55 seconds, the *ttl* is not changed. The
object expires after 125 seconds.
* If the object is **stale**, the expiry time is not changed.
When the expiry time of an object is reduced due to a softpurge, an
``EXP_Reduce`` entry is logged under the ``ExpKill`` VSL tag. If a softpurge
does not reduce the expiry time of an object, an ``EXP_Unchanged`` entry is
logged instead.
$Restrict vcl_hit vcl_miss
SEE ALSO
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment