Objects for ESI includes incorrectly miss
JT Justman
jt at endpoint.com
Tue May 20 06:08:15 CEST 2008
Hi, everyone. I've been doing my best to dig into the bug I opened:
http://varnish.projects.linpro.no/ticket/240
Basically, every object is inserted, but the second and subsiquent
objects always miss. The object goes to the MISS step in cache_center
cnt_lookup() where there is a check on sp->obj->busy. This seems to be
an indication that there was no object on the session.
cnt_lookup is called with a session that does not have an >obj
cnt_lookup is called from the 'STEP' system, from cnt_recv - which
itself doen't touch the obj, except to call 'AZ' on it, which I think is
a check.
RECV is called from fetch/RESTART, and cnt_start. And cache_vrt_esi. So
obviously ESI is expected to do something to the object that it isn't.
RESTART is calling Unbusy.
ESI_Deliver is setting RECV. The object is fiddled with but seems to
already exist.
Tried calling Unbusy in ESI_Deliver. No success. Can't modify the object
until after RECV.
ESI_Deliver is setting the document's object aside, and calling RECV
with a NULL'ed object.
Yes, the object to RECV is null.
Then it passes on to LOOKUP, still with NULL.
LOOKUP checks for null, allocates, and calls VCL_hash_method. I.e., the
manpage lies. vcl_hash manipulates req.hash.
Back in cnt_lookup. HSH_Lookup is called and assigned to local o.
HSH_Lookup locates objhead (?) then loops through the objects of
objhead(?). It looks to see if the object was busy, if it is
uncacheable, vary condition, banning, and grace period. Okay, I guess
objhead is a hash of objects. It's looking for one that it can work
with. If it finds one it likes, it returns it.
In our case, it is finding the object for one include, and not for the
other.
So how is the object getting into objhead?
There is a call to HSH_Prealloc. It pre-builds the objhead and object if
needed. Hmmm....
the objhead has some kind of queue functionality.
So if there is no objhead yet as of HSH_Lookup, then the empty one is
used, and a call to hash->lookup fills it, I guess. It only places
objhead into the session if there are busy items, otherwise into the
object. hash is a hash_slinger. I guess this is mapping the different
hash types.
So lookup seems to be accessing the store and looking for the object. I
guess it walks the hash looking for a match by comparing various values.
It calls HSH_Compare as the final check, then returns the matching objhead.
HSH_Compare is passed a session and an objhead. First it checks the hash
lenghts. Then it checks if the hash itself matches.
In our case, compare is returning 0 on both requests.
Back to hash->lookup. This falls to the second have of the loop. It
increases the header element's refcnt. Places the objhead in roh.
Unlockes mtx. Then returns roh.
So head back to HSH_Lookup. Now we've got the newly-retrieved objhead.
Which we are looping through. What is oh->objects exactly? It's a
VTAILQ_HEAD(,object) if that helps.
TTL value is broken! NaN! Staring me in the face!
So I think the date is funny. RFC2616_cache_policy is being called from
cnt_fetch. Afterwards TTL is correct.
More information about the varnish-dev
mailing list