You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Ben Hyde <bh...@gensym.com> on 1998/01/28 18:12:55 UTC

Adding new module callbacks.

This proposal arises out of Dean's recent frustrations
with avoiding the stat calls, and Randy's suggestion
to extend the module structure.  It's a pain that
extending the module structure is so expensive.  What's
in the module structure should only be what a module
must define, not all those things that are optional.

If people like it, maybe somebody can volunteer to
implement it.  This design would need a little sanding
before the varnish is applied.

  /* callback_name(s) are char* text strings.  They are
   * used to name callback entry points defined by the
   * core or modules.  The name is used when creating
   * new named callbacks and when registering a callback
   * with the core. */
  typedef char *callback_name;

  /* Callback_handles provide a handle on each callback
   * routine installed into the core by modules.  They
   * are created via ap_install_callback, and distroyed by
   * ap_deinstall_callback.  Each named callback has one
   * or more recorded for them. */
  typedef ... callback_handle;


  /* ap_install_callback notifies the core that it should
   * invoke the function f in the style implied by 
   * call_back_name in service of requesting_module.  This routine
   * may block momentarily if another thread is updating the
   * callback data structures.  The result denotes how things
   * worked out.
   *    status   implication
   *      0       wonderful
   *      1       deinstalled existing callback
   *     -1       no such callback
   */
  extern int ap_install_callback(
                callback_name name, 
                module *requesting_module, 
                random_function f
                callback_handle *result);

  /* ap_deinstall_callback notifies the core that it should
   * stop calling the function of this callback.  This maybe
   * invoked while a callback is in progress. Once this returns
   * the handle is no longer valid. This routine may block
   * while if another thread is updating the callback data structures. 
   * Return value denotes the status.
   *     0 all done.
   *    -1 unknown handle.
   */
  extern int ap_deinstall_callback(callback_handle handle);

Motivation:
  Enables the core to add new module callbacks without having
to recompile the existing modules.  A good thing as we move
to a DLL model for modules.  Great for unusual workarounds,
like prempting some of the phases.

We could even allow modules to define callbacks for the
use of other modules.

  /* A named_callback_handle provides modules with a handle
   * to the core internal knowledge of a particular named
   * callback.  Modules may create new named_callbacks with
   * ap_create_callback, and may invoke enumerate the functions
   * installed on named callback to implement the acutal
   * callback. 
   */	
   typedef ... named_callback_handle;

   /* ap_create_named_callback is used to create a new callback
    * routine in the core.  Other modules may then register
    * with this.  The creating module will invoke the functions
    * registered at the approprate times.  The boolean
    * parameter singular is used to note this more than
    * one module may register with this call back at the
    * same time.
   extern int ap_create_named_callback(
	callback_name name, 
	module *m,
        int singular
	named_callback_handle &result);

Motivation:

This allows the writing of modules that seem to appear to extend core
functionality.  This encourages the illustion that the core is just
a set of modules.

Example:

  "module-status-reporter" an ap_callback provided by mod_cool_status

    Modules may install a callback for "module-status-reporter"
    which when mod_cool_status is linked into the server will
    be invoked to request that they add some HTML content to a
    status page indicating the state of their internals.  The
    function installed should have the signature.
        void my_module_status(request_rec *r)


 - ben hyde

Re: Adding new module callbacks.

Posted by Alexei Kosut <ak...@leland.Stanford.EDU>.
On Wed, 28 Jan 1998, Ben Hyde wrote:

> This proposal arises out of Dean's recent frustrations
> with avoiding the stat calls, and Randy's suggestion
> to extend the module structure.  It's a pain that
> extending the module structure is so expensive.  What's
> in the module structure should only be what a module
> must define, not all those things that are optional.
> 
> If people like it, maybe somebody can volunteer to
> implement it.  This design would need a little sanding
> before the varnish is applied.

(I'll avoid my usual rant about how people should memorize all 40
megabytes (compressed) of new-httpd mail archives before they post
anything here. Be thankful)

This is a concept that has generally been accepted as part of the API
redesign for Apache 2.0. Once I get some free time and write up the ideas
that I've been collating, my ideas on this should become clear.

At any rate, yes, having modules register their functions using callbacks
is definitely in the stars for Apache. There are some other issues to be
considered, however, besides just simplification of the module structure:
Namely, one thing that we want is to reduce the chain of possible 
DECLINEDs that a module should go through before doing its thing. e.g., a
module that only serves data should (currently) check the method of ther
request, and return DECLINED if it's not GET. It should also set
r->allowed. However, many modules don't do this correctly. This can cause
Apache to behave incorrectly.

>From everyone's standpoint (the module author's, Apache's, etc...) the
easier thing to do is to register these sorts of things with Apache when
the callback is registered. This lets Apache decide when to call a module,
instead of the module having to worry about it.

Another issue is that of the "priority" (for lack of a better term) of
modules. Right now, each given phase has its available functions executed
in the reverse order of module configuration. This is often not the best
order. Modules should have some say, as they are loaded, or via user
configuration, over in what order they are to be executed.

Furthermore, the question of at which points a module can register a phase
has come up. Can a module only register callbacks at startup? Or can it
add it in the middle of a request, because it knows it will be needed
later? How does Apache handle this? Is it then added for all requests that
server is handling, from then on? Just for that request? Just that thread
(or whatever)?

Further questions, such as exactly which phases should be defined, and
which "options" are good for them to have, also need to be considered.

These, and other issues, have been discussed in the past WRT this issue,
and need to be addressed by any possible solution. It needs to be a
part of the general 2.0 API rewrite, I think, and shouldn't be pigeonholed
into 1.3. We decided that a long time ago.

There is also the issue of extensibility, and the ability to "clone" the
Apache API in other servers. This is a larger issue with the Apache API in
general, but there needs to be an easy way for servers to only support
some of the Apache request phases, and to allow modules to still run, and
gracefully degrade, on these servers. This is also true of, as we
discussed last month, backwards and forwards compatibility between
versions of Apache.

-- Alexei Kosut <ak...@stanford.edu> <http://www.stanford.edu/~akosut/>
   Stanford University, Class of 2001 * Apache <http://www.apache.org> *