You are viewing a plain text version of this content. The canonical link for it is here.
Posted to serf-dev@apr.apache.org by Greg Stein <gs...@lyra.org> on 2002/09/03 08:08:06 UTC

Re: cvs commit: apr-serf/docs notes-filter-chains.txt

[ catching up on this; I deferred it cuz it was, um, *long* :-) ]

On Wed, Aug 28, 2002 at 06:26:16PM -0700, Aaron Bannert wrote:
>...
> 1) Let's get away from the notion of Push and Pull, and go to the idea
>   where the app drives the filter chain, and each filter is given
>   control of a piece of data for a short period of time.

It appears that the model you describe below is a "full push" model. No pull
whatseover. That's fine with me, as I think it is the best way for an app to
be built.

Hmm. The general notion of a push model, including yours, can still be used
in a pull-mode if the app wants to do that. For example, the app can direct
the socket SOURCE to push some data into the graph. The SINK simply holds
onto the data and returns. The app then picks up the data.

>...
> 4) All graphs have by default two filters, a SOURCE and a SINK. The SOURCE
>   filter produces a single TRANSACTION (for lack of a better term),
>   and a SINK consumes the same.

I was about to add to some of the notes my thought that a completely push
model actually produces a "ring". You have a node that is the socket
send/recv, and it loops the input through the "input filters" and back
through the "output filters" to the socket again. Drawing it out, it
produces a ring. The "application" would be just another node in the filter
chain/ring.

You've formalized my description of the ring a bit better.

>...
> 6) The application then uses the filter graph. If there are any unused inputs
>   or outputs, there is an immediate runtime error. The reason this is deferred
>   until the filter graph is actually used is so that the contents of the
>   graph can be modified at any time. (One can imagine wanting to add or
>   remove certain filters after a particular filter graph has been used, so
>   why limit ourselves here?)

We'd want to look at the performance of graph setup/teardown. If it is
expensive, then you'd want to be able to define/resolve a graph, and then
reuse it over and over (which means that you want to isolate the definition
of a graph from its runtime data; e.g. the filters inserted do not carry a
*ctx field themselves (you could insert each filter with a data index, and
they recover their ctx from an array of ctx pointers, where the array is
per-transaction)).

>...
> Let's take a really simple example: Serving a static file via HTTP req/resp:
> 
>  - The types of filters I could imagine being involved here would be:

I would nitpick these :-), but let's defer that conversation. Generally,
your descriptions assumed too much info (how would the SOCKET_WRITER know
where the endof a TRANSACTION lies?), and an attempt at balance (your
diagram of "resolution") where one doesn't really exist. Basically, the SINK
doesn't know anything about transactions. It is a bytestream. For that
matter, same on the SOCKET_READER side: it just reads bytes and passes them
along; it is the following filters which define the concepts and, thus,
define the transactions boundaries.

>...
> Type System:
> 
> So now we're going to have an explosion of new data types, how do we
> manage this? My OOP training would love to be able to use a whole
> inheritance system to deal with this, and although we don't have that
> explicitly in the C language, I think that's what we're going to end
> up having. Imagine something like this:

I believe it will be flat, discrete types. But only belief... I'm not tussed
about either direction.

Cheers,
-g

-- 
Greg Stein, http://www.lyra.org/