Our first cut at a LRU processing contained a three way race and can
cause Really Weird Problems if you really provoke it.
+++ Redo from start +++
LRU processing is only relevant for objects which are in the cache and
on the EXP binary heap so we merge the LRU functionality with the EXP
code in order to share locks and object reference counts.
Another thing we overlooked in the first implementation is that the VCL
callout for LRU should be able to examine the client information for
the session which tries to push stuff out, so that QoS/DoS issues can be
considered:
sub vcl_dicard {
if (client.bandwidth > 10 mb/s) {
keep;
}
}
(which sort of indicates that "error" should be a legal action as well)
To enable this, pass the session into the stevedore when we try to
allocate space and temporarily substitute the target object for its
own object while we call vcl_discard().
The outcome of an attempt to make space can take three values, did,
didn't and couldn't. In the latter case there is no point in trying
again and again, in particular if the cause is incurable, such as
the requested size being larger than the storage. We still need to
handle failure to allocate storage for that case rather than core dump.
When looking for targets to nuke, we only consider objects on the
binheap which has reference count of 1, objects with higher reference
counts would not free space.
We take prospective targets off the binheap, but retain their
refcount, and tag them with a magic marker while we ponder their
destiny.
It is quite possible that another session could pick the object up
via the cache while we do so, and therefore attempts to update the
ttl or shift them in the lru chain must ignore objects which has
the magic marker. If the object is kept, the updated ttl will
automatically take effect when we reinsert it in the binheap.
git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@2006
d4fa192b-c00b-0410-8231-
f00ffab90ce4