httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Ben Hyde <>
Subject Re: Core server caching
Date Thu, 24 Sep 1998 14:55:36 GMT
Simon Spero writes:
>[This is going to be relatively short...]
my empathy on the hands I assure you.

>Cache invalidation can get pretty hairy in the most complicated cases-for
>example, when dealing with a module implementing a generic scripting
>language; however for native modules, it can be made relatively simple.
>If instead of treating dynamic objects which depend on a number of
>parameters as just glorified implementations of a generic GET  or POST
>method, they are instead implemented and declared as application oriented
>methods, which get called by the get or post handler, it becomes a lot
>easier to annotate those methods with cache validation information.  If
>we're trying to lose the assumption that we're always talking HTTP back,
>then this makes the design a lot cleaner.

Yes. The range of useful cache invalidation heuristics makes it difficult
to design a one size fits all invalidation scheme in the core.  While
a call back to validate is a good idea I think it can be put back a
little in the I/O stack from the base entry in that stack, but I do
think the base of the stack needs to have a cache of things it can
send quickly.

>some sort of I/O modules just add or subtract headers; others completely
>rewrite the contents.  The former can be implemented really efficiently,
>especially if high-level modules can pre-inform lower-level modules of how
>much extra space they will need for headers.

If things pushed late into the I/O stack are going to add headers you
have then you stuck blocking I/O for the entire response until they
unblock it.  Presumably the initial choice of response generator can
select if blocking is or isn't required.

>One distinction that is useful to keep in mind is the difference between
>streams that are connected to a network, and those are used to transfer
>data between parts of the server.  If I'm allowed to keep going with my
>three level model, the former connects the front-end to the middle-end,
>and the latter connects the middle end to the back-end; one end drains
>into the cache, and the other end drains out.

I'm not my model of "levels" and yours are in synch.  But yes.  As
soon as there is an I/O pipeline (or stack) then the protocol between
elements of the stack is, presumably, something different from HTTP.

>If all streams are connected via the middle-end, then intermediate stream
>content can potentially be cached.


My model of what flows on the pipeline is response_chunks of various
flavors and further more that it is useful to have send_cached_chunk
as one of those flavors at the bottom most stage in the pipeline.

>The job of the middle-end is to mediate such disagreements, and to apply
>architecture specific optimisations as much as possible-in particular
>TransMetaFile and its ilk, zero copy stacks, etc..

I see that as problem of designing a good I/O pipeline/stack,
i.e. that is can rapidly pass the high performance cases at
minimum overhead.  How many layers get stacked up varies both
from application to application as well as during the generation
of a single response.

>Depending on what sort of back-end module you use, there are several
>different ways of feeding data into middle-end that makes sense.  For
>modules that source their data from a file, the best way to parse the data
>is by filename.  For other modules, having a file handle makes more sense.
>Yet others are best suited to a mechanism using mbufs/sbufs-especially
>those that are performing transformations on the data. The internal object
>representing this data source can emulate all of these interfaces as long
>as one is implemented. If the data reaches the cache was originally
>sourced from a filename, then the cache should only be keeping the
>information about the mapping, and not the actual contents of a file.

Interesting.  My model was that the content generator (input of the
pipeline) would delimit portions of his output as being "cachable"
getting a cache id in return which he would reuse latter.  Meanwhile
at the tail end of the pipeline it would record the stuff between
the brackets for replay latter when requested.  It could of course
decide what to record, either a sequence of chunks or the
concatenation of those chunks into something it can ship out even
faster.  If he records the a transmit file chunk, and not the content
of that file then the guy holding the cache id must know that.

>Some types of back-end object, for example those based on files in an
>environment supporting mmap, may prefer to allocate there own memory;
>similarly, some types of front-end may work better if they allocate the
>memory for data to be stored in.  An example of this might be a system
>with a memory mapped network interface and a collaborative TCP

That's an example of why I want response chunks that flow down
the pipeline to be extensible with an atomic set at the base.

The pipeline design is a lot like the module API design problem.
It would be wonderful if it all works well enough that the
"module" can reside at assorted distances from the server
(same thread, same process, different process, different machine).

It seems to me useful to admit that the protocol/api/pipeline
within the server site can be and ought to be richer than HTTP is.

 - ben hyde

View raw message