The existing 2.x store_body interface passed a brigade to the storage 
provider's store_body() callback.  It is impossible for the provider to 
store all of such a brigade without consuming an arbitrary amount of 
RAM, since the brigade may contain morphing buckets (a CGI/PIPE bucket 
is the pathological case).  This is bad.

Ways to fix this that I can think of:

1) change the store_body interface to allow the storage provider direct 
access to f->next, so it can flush buckets up the output filter chain 
when they have been stored.  As seen on trunk.

2) keep the interface as-is, but read buckets in mod_cache and partition 
the brigade manually; only pass a "small" brigade with known-length 
buckets to the provider. (so no morphing and no arbitrary memory 
consumption)

3) change the interface: deal with the buckets entirely in mod_cache and 
just pass (char *,size_t) pairs to store_body

4) change the interface: pass some abstract "flush-me" callback in, 
which the provider can call to pass up then delete the bucket. 
(apr_brigade_flush doesn't quite fit the bill unfortunately)

IMO:

if you're going to be reading buckets from the brigade in mod_cache, you 
might as well go the whole hog and do (3), and stop exposing the 
provider to buckets or brigades at all.  This will prevent the provider 
from doing any particular optimisations based on content type (like 
copying FILE buckets); feature or bug, take your pick.

But if you're still going to expose the brigade to the provider, it's 
wrong to be reading the buckets into the mod_cache as well; just 
implement the provider as a little output filter, something like (1).

Regards,

joe

Reply via email to