Re: Filters != handlers [Was: [PATCH] A hack at first class filters]

2001-05-25 Thread Doug MacEachern

On Fri, 25 May 2001, barries wrote:

 On Thu, May 24, 2001 at 05:52:39PM -0700, Doug MacEachern wrote:
  let's consider everything before adding new code.
 
 Ok :-).  I have a reply in queue that works through your ideation w/
 questions  suggestions.  But first, let's look at really bifurcating
 the API into a Perl*Filter API and a more Apache-esque API.
 
 I'm starting to think that packaging low level Apache filters as though
 they were Perl*Handlers is a misleading API: they're different from
 plain handlers and treating them so is likely to mislead developers and
 provides different semantics than the underlying Apache API provides,
 leading to impedance mismatch in mod_perl's implementation and in
 devloper's mental models.
 
 Other handlers get called once per request or subrequest.  Filters will
 often get called 2 or many, many times (see any handler that skips
 sending an EOS bucket, as well as mod_isapi and mod_proxy). Writing a
 filter sub requires a much more event-driven mindest than writing a
 handler sub: even the example reverse filter has a surprise in it waiting
 for somebody that slaps it in front of mod_proxy or mod_isapi or any
 other handler that sends multiple bbs of content.
 
 Handler subs are simple use-once event handlers no intra-request state
 needs to be kept.  Filter subs will often need to be aware of BOS/EOS
 state provided by mod_perl, and will also need to keep some
 intra-request state.

to me, a Perl*Handler is just a configuration directive which specifies
the name of a Perl subroutine.  and that subroutine is called during a
given apache plugin callback.  all Perl*Handlers, including filters use
the same mechanism for resolving the name, loading the module if
needed, calling the subroutine, etc.
 
 So, how about two APIs?

isn't this what i've been saying all along? :)
 
 API 1: Perl{In,Out}putFilterHandlers
 
 Perl{In,Out}putFilter directives act much like todays, but use the
 filter name when registering filters and AP_FTYPE_...CODE attrs to
 modify when ap_add_xxx_filter()s get called.  The only reason for using
 the filter names is to enable debug dumps of the filter stack to be
 read, and to obey the principle of least surpise, meaning that there's
 no need for the special-ness of MODPERL_{IN,OUT}PUT_FILTER_NAME to be
 grokked by hapless mod_perl-internals-geek-wannabes like me.

sure, i'm all for using the Perl name to register the filter.
 
 However, to make these Perl{In,Out}putFilterHandlers consistent with
 other Perl*Handlers, mod_perl would need
- to buffer all filter input in an ever-growing bucket brigade until
  EOS is seen,
- then call the Perl*FilterHandler sub (once!),

i would consider this as an option.  it could actually be a standalone
filter module that collects all brigades into one before sending it
further down the chain.  if its proven to be efficient, we can make it the
default.

- passing it $r blessed in to an Apache::RequestFilter (or some such)
  class which would have alternative I/O subs that called the brigade
  APIs.  Would also provide a filter() accessor to get at the
  real Apache::Filter object for the rare case when that might be
  needed in sucha high level handler.

$filter-r gives you the request_rec.  Perl*Handlers in 2.0 are passed
the same arguments as C handlers are passed.

- and pass on the EOS when the sub exited.
 
 The coding style would be very consistent with the existing mechanisms
 and all the hairball stuff you can trip over with filters is balled up
 into a tangle of wiring hidden behind nice, padded walls. No BOS/EOS
 worries, not statefullness worries, just memory and (possibly) latency
 worries.

i hope we can get to that.  the C bucket brigade api is klunky.  the
$filter-{read,write} methods written as part of the padding, still need
to be implemented for input filters.
 
 The worries in that scheme, as well as the lack of flexibility in
 calling ap_add_xxx_filter() need a low-level API to handle.
 
 API 2: Bucket Brigade filters

i think we're on the same page, this is pretty much the same as what 
i outlined under 'direct C api mapping.

 mod_perl could call ap_register_xxx_filter() on all subs compiled with
 either an AP_FTYPE_FOO or a new MP_INPUT_FILTER or MP_OUTPUT_FILTER sub
 attr.

except for this part.  for the direct mapping, mod_perl should not do
anything special.  it will be up to the Perl filter module to call
Apache::register_xxx_filter with AP_FTYPE_FOO.  i'm ok with defaulting
arguments, e.g. ftype could default to AP_FTYPE_CONTENT.



-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]




Re: Filters != handlers [Was: [PATCH] A hack at first class filters]

2001-05-25 Thread Doug MacEachern

On Fri, 25 May 2001, barries wrote:
 
 Ok, I think I was underestimating how much padding you wanted on the
 direct C API mapping.  I thought that that would be 0 padding (like how
 the ctx param to $r-add_output_filter() is treated).

i would like 0 padding for the 'direct' mapping.  the padding aside from
Perl*FilterHandler's taking care of registration/adding is to provide the
stdio-like interface, $filter-{read,print,etc}.  and maybe a bit more to
have an option where brigades are merged so a filter handler is only
called once per-request.
 
 So I was seeing three layers: Perl*FilterHandler-installed filters with
 lots of padding, The Bucket Brigade filters, with enough padding to
 make bucket brigade writing easy yet efficient (relative to
 Perl*FilterHandlers, anyway), and C level API, which is very low level
 and probably needs a little XS or Inline::C code to make much use of it.
 That's what I get for reading not-yet-polished code (the C level API)
 and assuming...

much of the brigade/bucket api has been polished, though there might be 
some missing methods.  its the registration/adding of filters thats not
really been touched yet.

 I think the main point of what I'm talking about here (the Bucket
 Brigade filters) is to get enough padding and automation built in that
 it doesn't take any more Perl code to write them than it does to write
 Perl*Handlers, even though it's tricker code.  I couldn't see how to add
 that level of padding to the C API without hiding the low level peices.

right, $filter-{read,print,etc} is attempting to hide the low level.
 
 Ok, now I see two alternatives: I'm saying use CODE attrs on subs you
 want auto-registered and call the C level ap_register_xxx_filter()
 wrapper if you want to register something manually, passing in the
 optional AP_FTYPE_FOO constant.
 
 You're saying to always use the ap_register_xxx_filter() manually all
 the time unless you use the Perl*FilterHandler directive.  In this case
 the ap_register_xxx_filter() would need to arbitrate between any CODE
 attrs and whatever AP_FTYPE_FOO the user passed in (if they passed one
 in).

i suppose if no AP_FTYPE_ is passed to ap_register_xxx_filter(), mod_perl
could first look for sub attributes, if there are none, then default to
AP_FTYPE_CONTENT.


-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]