The stevedore API
Poul-Henning Kamp
phk at phk.freebsd.dk
Thu Nov 13 10:02:14 CET 2014
I've been mucking about with the stevedore api for some days in order
to resolve a number of silly issues, including the vast overallocation
for tiny objects when streaming.
There are suprisingly many dead ends in this area.
I think I have finally managed to come up with something that is usable,
both from stevedore and varnishd side.
The crucial insight is that we do not need to store the OA first
since we now have accessor functions. Instead we can collect the
OAs in the busyobj until we know their final size, and only then
allocate space for them.
But we still need to alert persistent stevedores before we make the
first allocation for a new object, and we also (which is new!) want
to give stevedores a chance to relocate segments once their size is
known for sure. In that case it's the stevedores responsibility
to keep track of streamers of the interrim segment before freeing it.
Persistent stevedores also must be told what "magic key" it must
present to resurrect an object.
And finally we make it the cache_obj.c codes responsibility to free
all allocated segments individually, so that the stevedore does not
need to keep track of that.
Seen from the stevedore:
New objects are created with stv->newobj().
Arguments:
busyobj
total size estimate
Returns:
yes/no
busyobj/objcore has private field(s) for the stevedores
private use from here on.
The stevedore can fail this if the object is undesirable,
and another stevedore will be attempted, if nothing else, Transient.
Storage segments are allocated with stv->alloc()
Arguments:
busyobj
desired number of bytes
Returns:
interrim seg_id (uintptr_t)
data pointer
length
Once the segment has been written to: stv->commit()
Arguments:
busyobj
interrim seg_id
length used
Returns:
final seg_id, may be different from interim seg_id
Other threads may reference segments with stv->ref()
Arguments:
busyobj (possibly NULL)
seg_id (interrim or final)
Returns:
data pointer
length
References are released with stv->rel()
Arguments:
busyobj (possibly NULL)
seg_id (interrim or final)
Returns:
none
Object is finalized with stv->final()
Arguments:
busyobj (not NULL)
seg_id (key to resurrect persistent object)
off_t (subkey to resurrect persistent object)
Returns:
none
Objects are killed with stv->deleteobj()
Arguments:
objcore
All allocated segments are individually freed with stv->free()
Arguments:
seg_id
Seen from varnishd:
stv->newobj()
collect OA's in busyobj and access from there
stv->alloc/commit until body is received
all OA's defined.
byte-stream encode OAs into last storage segment
(including OA listing storage segment id's)
(if space allows) else into separate segment
stv->final(coords for OA bytestream)
OA's now pulled out of stored object
Comments most welcome...
--
Poul-Henning Kamp | UNIX since Zilog Zeus 3.20
phk at FreeBSD.ORG | TCP/IP since RFC 956
FreeBSD committer | BSD since 4.3-tahoe
Never attribute to malice what can adequately be explained by incompetence.
More information about the varnish-dev
mailing list