[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [cgiapp] Re: Yet another callback system proposal


On 5/20/05, Mark Stosberg <suppressed> wrote:
> > Well, I was pretty conservative (read: timid) in my numbering.  We could
> > obviously change it to:
> >
> >     FIRST         => 1
> >     MIDDLE        => 50
> >     DONTCARE      => 50
> >     LAST          => 100
> >
> > Then the names don't lie, and people can use the numbers if they
> > really need precise control.
> 
> I don't think numbers really help with precise control, because the
> control desired is to have an affect on loading position relative to
> other plugins which we are out of your control.

I think we need to clarify what we are talking about.  It is not the
order of the loading of the plugins that is at issue.  It is the order
that the callbacks get executed that is at issue.

These two are related, since plugin writers will most likely register
callbacks at one of two locations:  when they are loaded, or when they
are configured.  Of course there are other times when a callback can
be registered, but I would think the above two will be the most
common.

> So, requesting position "1" doesn't stop another author from doing the
> same and causing a conflict. Requesting position "1" also doesn't
> communicate anything about /why/ the first position is desired, which is
> probably because it needs to load first relative to something else.
> Which brings us to the next topic...

It is even more complex than that when we take into consideration the
ability to register a callback at the class level and at the object
level (which I believe is what Michael's patch aims to do, and it is
one of the things that I think is necesary).

I could register a prerun callback in my parent class (which would get
executed for any of it's subclasses), and another plugin might
register a prerun method just for the current object.

So if we have a hierarchy like this
CGI::Application
  My::App
    My::Admin
      $self   ( a My::Admin object )

Then we could register a prerun callback at any one of the classes and
at the $self level, and these prerun methods would need to be ordered
somehow so they execute in a predictable way.  Note that by default a
callback is registered at the CGI::Application level called
'cgiapp_prerun' which implements the current way of running code at
the prerun stage.


> >> If the plugin loading becomes complex, it probably won't be numeric
> >> slots that will be most helpful, but being able to express something in
> >> terms a human could actually understand, like "this needs to be loaded
> >> after the database handle is available".

Again, we are talking about executing callbacks, not loading plugins. 
I think it is an important distinction.

> > I was thinking about exactly this sort of thing!  If this approach is
> > not considered to be too complex, I'm willing to take a stab at it.
> >
> > I guess the question is how to express the dependencies?
> 
> How are the OSes handling this for advanced init script systems? It
> seems like the same issue. (And not one I'll claim to be familiar with).

That is one of the reasons why I think the numbering system is easy. 
It is already used by the init system.  It is also used by the perl
testing frameworks to define the order that tests are executed.  You
are effectively assigning and orderable value to your callbacks so
that the system can sort them and execute them in a predictable way.

Also, I should note that I believe that ordering is unimportant in
almost all cases, and should only be used if absolutely necesary.

> > For instance,
> > how does a plugin request a callback "after the configuration module has
> > loaded"?
> >
> > We could do:
> >
> >    $caller->add_callback('init', 'my_setup', {
> >        'DEPENDS_ON' => 'CGI::Application::Plugin::ConfigMumble',
> >    });
> >
> > But the obvious problem here is that there are at least three CAP config
> > modules out there, so how does the plugin say "after whatever
> > configuration plugin the user happens to prefer"?
> >
> > Or does each plugin indicate its "provides" and "requires" properties
> > when it requests the callback?  Something like:
> >
> >    $caller->add_callback('init', 'my_setup', {
> >        'POSITION' => 'FIRST',
> >        'PROVIDES' => [ 'log' ],
> >        'REQUIRES' => [ 'config', 'database' ],
> >    });
> >
> > That could work.  We could even make it so that a module automatically
> > 'provides' its own package name, so that plugins can explicitly require
> > a specific plugin by name if they need to do that.
> 
> Parts of this is good. I don't see a benefit to adding "Depends on
> Module name..." logic. That seems like re-inventing "use Module::Name".
> 
> What's interesting here is having abstract services that are provided,
> like logging or a database handle.

Thinking of this as services is again talking about loading plugins as
opposed to executing callbacks.  I think a better way to think about
it is in terms of actions.  Here are a few examples:

- Authentication needs to be performed before Authorization
- Flushing a db session needs to be performed before the db handle is destroyed.

We don't care that the session plugin may need the DB plugin that is a
different problem that should be solved elsewhere.  But we do care
that the session needs to be flushed before the DB handle is
destroyed.

> Let me backup and express a more general philosophy. As software
> releases evolve, it's easy to make them more complex and be backwards
> compatible. It's hard to make them simpler without breaking something.
> 
> While I think there is more interesting discussion to be had about the
> "provides" and "requires" ideas, as well as numeric positions, in terms
> of releasing something soon, I'm most interested in the simplest
> possible working solution. Assuming it's a good foundation, we can build
> on it later to make it more complex if deemed necessary.
> 
> Would I would find most useful now is specific evaluation of the
> proposed basic position system. Is it a good enough foundation to start
> with? If not, let's discuss the fundamental flaws and let that flavor
> proposals to adjust it.

Well how about this for a radical proposal...  Lets drop positioning
completely from the first version!  If it is not there, then it will
be easy to alter later.  I think once we have a system where people
can actually start using the callbacks, we will see the requirements a
lot quicker and be able to deal with them appropriately when we have a
better (clearer) understanding of the problem space.

We still need to be consistent in the execution so that it is
repeatable, but we can use a simple fifo system where the first
callback registered is the first to be executed.  Some control can
still be had in the execution order by reordering the loading of
plugins or registering of callbacks and such...

What is important to me right now is to have a system of callbacks
that can be registered at the class level and at the object level. 
Ordering is not that important to me right now, and won't be until we
have a lot of plugins that use the callbacks system.  If a user uses
the callbacks without using any of the plugins, then they control
exactly when all the callbacks get registered, so ordering is not
important there.  It only comes into play when using third party
plugins, and even then we may find that it is a solvable problem
without resorting to strict positioning of callbacks.

Cheers,

Cees

---------------------------------------------------------------------
Web Archive:  http://www.mail-archive.com/suppressed/
              http://marc.theaimsgroup.com/?l=cgiapp&r=1&w=2
To unsubscribe, e-mail: suppressed
For additional commands, e-mail: suppressed


Mail converted by mhonarc 2.6.15
This archive provided courtesy of JSW4.NET, Internet Hosting Services for Small Business.