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

cache_ban: Add obj.last_hit #4287

Open
wants to merge 1 commit 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
8 changes: 7 additions & 1 deletion bin/varnishd/cache/cache_ban.c
Original file line number Diff line number Diff line change
Expand Up @@ -498,7 +498,7 @@ ban_evaluate(struct worker *wrk, const uint8_t *bsarg, struct objcore *oc,
int rv;

/*
* for ttl and age, fix the point in time such that banning refers to
* for ttl, age and lru, fix the point in time such that banning refers to
* the same point in time when the ban is evaluated
*
* for grace/keep, we assume that the absolute values are pola and that
Expand Down Expand Up @@ -546,6 +546,12 @@ ban_evaluate(struct worker *wrk, const uint8_t *bsarg, struct objcore *oc,
darg1 = oc->keep;
darg2 = bt.arg2_double;
break;
case BANS_ARG_OBJLASTHIT:
if (isnan(oc->last_lru))
return (0);
darg1 = 0.0 - oc->last_lru;
darg2 = 0.0 - (ban_time(bsarg) - bt.arg2_double);
break;
default:
WRONG("Wrong BAN_ARG code");
}
Expand Down
5 changes: 3 additions & 2 deletions bin/varnishd/cache/cache_ban.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,8 @@
#define BANS_ARG_OBJAGE 0x1d
#define BANS_ARG_OBJGRACE 0x1e
#define BANS_ARG_OBJKEEP 0x1f
#define BANS_ARG_LIM (BANS_ARG_OBJKEEP + 1)
#define BANS_ARG_OBJLASTHIT 0x20
#define BANS_ARG_LIM (BANS_ARG_OBJLASTHIT + 1)

#define BAN_ARGIDX(x) ((x) - BANS_ARG_OFF_)
#define BAN_ARGARRSZ (BANS_ARG_LIM - BANS_ARG_OFF_)
Expand All @@ -116,7 +117,7 @@
// has an arg2_double (BANS_FLAG_DURATION at build time)
#define BANS_HAS_ARG2_DOUBLE(arg) \
((arg) >= BANS_ARG_OBJTTL && \
(arg) <= BANS_ARG_OBJKEEP)
(arg) <= BANS_ARG_OBJLASTHIT)

/*--------------------------------------------------------------------*/

Expand Down
52 changes: 47 additions & 5 deletions bin/varnishtest/tests/c00059.vtc
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ varnishtest "test ban obj.* except obj.http.*"
# see c00021.vtc for obj.http.* tests

server s1 {
rxreq
expect req.url == "/old"
txresp -status 204
rxreq
txresp -bodylen 1
rxreq
Expand All @@ -15,11 +18,25 @@ server s1 {
txresp -bodylen 5
rxreq
txresp -bodylen 6
rxreq
txresp -bodylen 7
} -start

varnish v1 -vcl+backend {} -start
varnish v1 -vcl+backend {
sub vcl_deliver {
set resp.http.hits = obj.hits;
}
} -start

client c1 {
txreq -url "/old"
rxresp
expect resp.status == 204

txreq -url "/old"
rxresp
expect resp.status == 204

txreq
rxresp
expect resp.bodylen == 1
Expand Down Expand Up @@ -55,7 +72,7 @@ client c1 {
expect resp.bodylen == 2
} -run

varnish v1 -cliok "ban obj.ttl <= 2m"
varnish v1 -cliok "ban obj.status == 200 && obj.ttl <= 2m"

client c1 {
txreq
Expand All @@ -75,7 +92,7 @@ client c1 {
expect resp.bodylen == 3
} -run

varnish v1 -cliok "ban obj.age < 1m"
varnish v1 -cliok "ban obj.status == 200 && obj.age < 1m"

client c1 {
txreq
Expand All @@ -95,7 +112,7 @@ client c1 {
expect resp.bodylen == 4
} -run

varnish v1 -cliok "ban obj.grace == 10s"
varnish v1 -cliok "ban obj.status == 200 && obj.grace == 10s"

client c1 {
txreq
Expand All @@ -115,12 +132,37 @@ client c1 {
expect resp.bodylen == 5
} -run

varnish v1 -cliok "ban obj.keep == 0s"
varnish v1 -cli "param.set ban_lurker_age 0.1"
varnish v1 -cliok "ban obj.status == 200 && obj.keep == 0s"
delay 1

client c1 {
txreq
rxresp
expect resp.bodylen == 6

txreq
rxresp
expect resp.bodylen == 6
expect resp.http.hits == 1
} -run

# now we should have two objects, /old from the beginning and the len==6 object
varnish v1 -cliexpect { 2 C} "ban.list"
varnish v1 -cli "param.set ban_lurker_age 600"
varnish v1 -cliok "ban obj.last_hit < 1s"

# /old survives, but len==6 gets removed
client c1 {
txreq -url "/old"
rxresp
expect resp.http.age > 0
expect resp.http.hits == 2

txreq
rxresp
expect resp.bodylen == 7
expect resp.http.hits == 0
} -run

# duration formatting - 0s is being tested above
Expand Down
1 change: 1 addition & 0 deletions include/tbl/ban_arg_oper.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ ARGOPER(BANS_ARG_OBJTTL, BANS_OPER_DURATION)
ARGOPER(BANS_ARG_OBJAGE, BANS_OPER_DURATION)
ARGOPER(BANS_ARG_OBJGRACE, BANS_OPER_DURATION)
ARGOPER(BANS_ARG_OBJKEEP, BANS_OPER_DURATION)
ARGOPER(BANS_ARG_OBJLASTHIT, BANS_OPER_DURATION)

#undef ARGOPER
#undef BANS_OPER_STRING
Expand Down
3 changes: 3 additions & 0 deletions include/tbl/ban_vars.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ PVAR("obj.grace",
PVAR("obj.keep",
BANS_FLAG_OBJ | BANS_FLAG_DURATION,
BANS_ARG_OBJKEEP)
PVAR("obj.last_hit",
BANS_FLAG_OBJ | BANS_FLAG_DURATION | BANS_FLAG_NODEDUP,
BANS_ARG_OBJLASTHIT)
#undef PVAR

/*lint -restore */
22 changes: 20 additions & 2 deletions vmod/vmod_std.vcc
Original file line number Diff line number Diff line change
Expand Up @@ -612,10 +612,15 @@ The format of *STRING* is::

* duration fields:

* ``obj.ttl``: Remaining ttl at the time the ban is issued
* ``obj.age``: Object age at the time the ban is issued
* ``obj.ttl``: Remaining ttl
* ``obj.age``: Object age
* ``obj.grace``: The grace time of the object
* ``obj.keep``: The keep time of the object
* ``obj.last_hit``: Time since the last hit

``obj.ttl``, ``obj.age`` and ``obj.last_hit`` are relative to the submission
time of the ban, such that they represent a fixed point in time despite
being specified as a duration.


* *<operator>*:
Expand Down Expand Up @@ -662,6 +667,19 @@ non-existing header, the operators ``==`` and ``~`` always evaluate as
false, while the operators ``!=`` and ``!~`` always evaluate as true,
respectively, for any value of *<arg>*.

``obj.last_hit`` can be used almost as a "last accessed" time, so, for example,
``ban obj.last_hit > 1d`` removes all objects which were last accessed more than
one day ago. Also, it can be used to remove objects stuck at request bans by
issuing ``ban obj.last_hit > X``, with X being slightly less than the time since
the request ban.

``obj.last_hit`` is based on an internal last LRU time, which might not be
implemented by all storage engines. Where it is not available, ban expressions
using ``obj.last_hit`` evaluate to ``false``, which means that the respective
ban behaves as if it was not present. Where implemented, the last LRU time might
only get updated by the ``lru_interval`` parameter, which therefore is the
maximum precision of ``obj.last_hit`` bans.

$Function STRING ban_error()

Returns a textual error description of the last `std.ban()`_ call from
Expand Down