cocoon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Leo Sutic" <>
Subject RE: [Kernel22] How to develop a component?
Date Thu, 08 Apr 2004 17:28:50 GMT

> From: news [] On Behalf Of Leo Simons
> Leo Sutic wrote:
> > This is contrary to Avalon semantics, where a component reference, 
> > once obtained, remains valid until it is released.
> right. It's contrary to java semantics, even.

Not really. It is more like the semantics you have for
remote objects. Except we don't throw RemoteException all the time.
(But neither does AltRMI, if I remember correctly.)

> Yep. Nothing to do with avalon-framework, though. I would say 
> you'd have to [...]

> Agreed, its not very clean.

I have listed some other thoughts that I and Pier have thrown back
and forth below.

> All this, however, does not mean:
> "If you have two blocks in the avalon sandbox, you could share them 
> between them, but there is no (easy? elegant?) way you can pass them 
> arond *OUTSIDE* the sandbox and still allow blocks to be hotswappable 
> and runtime polymorphic."

No, it doesn't. (Tell it to the person you quoted, though.)

> IOW, What you have shown here is that new-style cocoon blocks are 
> incompatible with a standard assumption in most java code, namely, 
> that references will remain references. You have not shown that 
> these kinds of components cannot be used in an application where 
> you violate that assumption, only that it will result in headache.


> I can't see how it is relevant whether a reference is obtained 
> through the avalon ServiceManager or through any other means.


We have a set of components communicating across defined interfaces.

We want to be able to hot-swap the components. The interfaces are
considered permanent and need not be how-swapped.

We'll consider the simplest case.

Component: The component being swapped in this scenario. It consists
of implementation code, no interfaces. We make no assumptions regarding
the statefulness or statelessness of the component.

Client: The code using the component. The client is probably another
component, but we'll call it "client".

Container: The container in which we find the client and the component.

Wire: The connection between component and client. The important thing
with this wire is that it can be severed by the container. A component
(such as the client) obtain these wires by a lookup() operation, and
releases them via a release() operation. It is not defined just how
these two operations are done by the client, but the client can do them.

Client uses component. Component is to be hot-swapped. What does client
percieve when component is swapped? I.e. from the client's point of
what happens?

  And these are the alternatives that I know about...

ALT1: Wires are severed immediately, the component is reloaded.

Advantages: We know what happens with some certainty. The client will
get a big fat InvalidWireException thrown in its face, and have to deal
with it - but we know that this will happen and can thus code for it.
This is what happens when you run a distributed app / DB connection
so it's really not something that's unheard of.

Disadvantages: Coding for that InvalidWireException can turn into
a mess. 

ALT2: Wires are left intact and the new component is loaded in parallell
with the existing component. All future lookup() operations will return
a wire to the new component, and the old component will be undeployed
when all wires to it has been release()'d.

Advantages: A smooth phasing-in of the new code. No exceptions thrown.

Disadvantages: A bit of a problem if the component was supposed to be
a singleton, or if it accesses some shared resource, such as a log file.
Suddenly, you have two instances of something that should only have
one instance. Additionally, you'll never know if there is some wire
that's unreleased, so if you hotswapped a component due to a serious
fix, you can't ever find out if the new code is really running
in the system.

ALT3: Slap a read-write lock on every wire. When a component is about to
be undeployed, get a write lock on every wire before severing them.
Client must do a lock()/unlock() operation around blocks of code where
it can't handle the severing of a wire.

Advantages: Works perfectly well in theory.

Disadvantages: Deadlocks - but we can make lock() fail instead of block
to get around this. Perhaps. Harder to implement than alt 1 or 2. 


View raw message