Gang,
Before
going further on the Activators, I cleaned up the code
a bit
to make it easier to grasp. Activation events handling
(from 1.x) is
now merged into 2.x ActivationDelegate. This
allowed to remove
duplicated code throughout the Structure.
I also added tests that
ensure that PassivationException stack
traces contains every
encountered error (from ActivationEvent
listeners, Activators, the
Activatee and its children).
I feel that the high level
activation execution model should be
settled before we discuss the
"Activator as fragments" route.
The Activation acts on Structure
and Services (ServiceReferences).
Both Structure elements
(Application, Layer, Module) and Services
support event listeners
*and* Activators.
On Application activation: Structure is eagerly
activated ;
Services are lazily activated ; except if they are
instantiatedOnStartup().
Passivation occurs in reverse order.
Here is the
actual execution and error handling model. I'm sure
this will
raise comments.ActivationFail-fast
execution order is:
- Fire ACTIVATING ActivationEvent
- Call
beforeActivation() on each Activator
- Call activate() on
children
- Call afterActivation on each Activator
- Fire
ACTIVATED ActivationEvent
If an Exception is thrown,
already activated nodes are passivated.
@throws
ActivationException with first Exception of activation
plus the
PassivationException if any
PassivationFail
safe execution order is:
- Fire PASSIVATING ActivationEvent
- Call
beforePassivation() on each Activator
- Call passivate() on
children
- Call afterPassivation() on each
Activator
- Fire PASSIVATED ActivationEvent
@throws
PassivationException after passivation with all Exceptions
of
passivation if any
IOW, Passivation continue regardless of
Exceptions and raise a
PassivationException that has every errors in
its stacktrace
(thanks to Java 7 suppressed exceptions).
This
is far from ideal since errors during Passivation can lead to
invalid
state. Here is an example: given an Activator that do some
work on
passivation and a PASSIVATING event listener, when
passivating, the
event listener is called first, then, what if the
Activator depends
on something done in the listener?
At this point I still don't
know how to ensure application
developers can't create such a
situation while providing
understandable and solid passivation. Any
idea?
Finally, if we enhance Activators to become composite
fragments,
we would have to remove their support on Structure
elements as
they aren't composites.
Cheers
/Paul