avalon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Berin Loritsch <blorit...@apache.org>
Subject Re: [vote] lifecycle exceptions
Date Thu, 12 Apr 2001 14:35:29 GMT
Stephen McConnell wrote:
> >From Pete:
> -1 Some things are startable without being stoppable and vice versa.

Please read my entire message below.  I will provide a separate pattern
that we could/should adopt for startable() but not stoppable().  It
just doesn't make any sense to stop something you never started, so
the stoppable really shouldn't be alone.

> >From Steve:
> >   startable but not stoppable == dangerous, -1
> >   stoppable but not startable == autonomous and manageable, 0
> >
> >   We could define this as:
> >
> >       interface Stoppable
> >       {
> >           void stop() throws StopException;
> >       }
> >
> >       interface Startable : Stoppable
> >       {
> >           void start() throws StartException;
> >       }

Ok.  This is my best stab to voice arguments and provide a possible direction.

The approach Steve is using for his Components is somewhat like the "Composite"
pattern described in Addison-Wesley's book on design patterns.  Basically, it is
easier to have all managed components controled by a managing component to use
the same interface (Stoppable) and simply call the stop() method that is guaranteed
to be there for all managed components.

This is a very valid approach, and makes things like constructing new Compound
Composites (Composites that include Composites) very easy to do.  Our interfaces
should strive to allow an implementation neutral view of the world (as much as
is possible).

Peter's approach is that he has some components that he has designed execute for
a specific amount of time, and then die naturally.  I think there is a different
approach for this that would be beneficial.

So we have to decide pros and cons for separating start() and stop() interfaces.

Interface                 Pros                      Cons
start() without stop()    (1) Allows for letting a  (1) Not very manageable,
                              thread run until it       the thread is still
                              dies naturally            running when the manging
                                                        component is stopped()
stop() without start()    (1) Easily allows for     (1) No practical cons, only
                              Composites to             cleanliness of API issues
                              propogate the stop()
                              to all children
stop() and start()        (1) Allows for any kind   (1) Does not guarantee
separated                     creational or             manageability
                              behavioral pattern
start() and stop()        (1) Guarantees            (1) These two actions are
combined                      manageability             inextricably tied to
                          (2) Easily allows for         each other
                              Composites to
                              propogate the events
                              to all children

Given the pros and cons, I beleive in the end that it is MOST correct to tie
the start() and stop() methods together.  In a server environment, predictability
and maintainability are very strong concerns.  There is another pattern that
better suits Peter's needs.

In fact, when looking at the possible needs for the runtime interfaces
(Startable, Stoppable, Suspendable, Resumable), they should be natural

1) Startable and Stoppable should be combined for maintenance and
   management reasons.
2) Suspendable and Resumable are another natural pair.
3) Conceptually speaking, you can't have Suspendable/Resumable without

So my final proposal for the runtime interfaces is this:

interface Executable {
    void start();
    void stop();

interface Interruptable extends Executable {
    void suspend(); // should this be interrupt()?
    void resume();

Regarding the case where something is "startable" with no direct control over
when it stops, I want to promote the "Command" pattern.  Basically you have
an object that acts as a proxy for an asynchronous process that must run to
completion.  The runtime interfaces are mainly for classes that will run for
the entire duration that the Component allows it (i.e. the entire time between
start() and stop() minus the times it is interrupted).  This means that we
must explicitly start and stop the process--it is an active component.

The "Command" pattern encapsulates an action or set of actions in a command
object that many times is run asynchronously (though not necessarily).  The
"Command" pattern has a real need in many contexts from servers to Servlets.
In fact, the original Timer code that Federico committed used this pattern.
Basically, we would have an interface for the Command object like this:

interface Command {
    void execute();

We would either provide a CommandQueue, or have that command object start
after the Component it affects is fully set up.  The main point of the
Command object is that it is lightweight and it is tightly coupled to
a Component.

A component would have to expose, or register, this command object that
would have access to protected members.  I envision something like this:

interface Commandable {
    Command[] getCommands();

If a Component is Commandable, then the Commands can be executed between
the time the Component is fully Initialized adn the time the Component
is Disposed.

To unsubscribe, e-mail: avalon-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: avalon-dev-help@jakarta.apache.org

View raw message