Abstract Lifecycle Strategy Proposal

After playing around with a bunch of diagrams, I came up with an abstract model of what a container does to a component at a rather high level of abstraction - together with a mapping of this abstraction down to the Avalon notion of component lifecycle and container related concerns.

  potential 
      | 
      |                candidate 
      |                    | 
      |                    | 
      |-- establishment -->|                 component 
      |                    |                     | 
      |                    |--- deployment ----->|  
      |                    |                     | 
      |                    |<-- decommissioning -|  
      |                    | 
      |<-- termination ----| 
      | 

The above diagram presents an abstract state machine from a container's point-of-view.

Abstract Phases

Establishment Phase

Potential components exist as a result of a containment systems discovery process (classpath, meta-info and meta-data scanning, etc.). The establishment phase is about the creation of a "candidate" component - involving validation of meta-info and meta-data, assignment of a lifestyle handler, assembly of dependencies, and finally, verification that all logical dependencies are satisfied.

Deployment Phase

Moving from "candidate" to "component" is where we get into the Avalon framework side of things. This involves object instantiation application of a logging channel, contextualization, servicing, initialization, and potential startup. I've referred to this as the deployment phase. What is important to note is that that Avalon has particular idea of what deployment means - but no formal notion of deployment as a phase.

If we look into deployment in more detail (still maintaining an abstraction above the Avalon framework model) there are a number of particular stages that we can separate out as distinct and significant.

The deployment sub-stages include:

In Avalon the "logging strategy" is based on the LogEnabled interface and the assignment of a logging channel via that interface. What is important to note is that this is potentially one of may different logging strategies providing we can abstract ourselves above the stage implementation and into the notion of strategy definition.

The Avalon configuration strategy is basically the combination of Configurable and Parameterizable. The Avalon context strategy is the combination of the Contextualization and Service stages. An finally, the Avalon initialization strategy is represented by the Initializable interface and methods on the Startable interface or possibly the Executable interface.

Decommissioning Phase

The decommissioning phase is simply the process of bring an component back to something equivalent to a pre-initialized state. This is basically equivalent to the Avalon notion of suspension. Once decommissioned, the component can be re-deployed during which it picks up any non-final artifacts in relevant deployment stages (logging, configuration, context, etc.).

Termination Phase

The termination phase eliminates the component and is basically equivalent to the current Avalon notions of Startable.stop() and Disposable.dispose().

Benefits

I think the above is a rational approach to addressing some key issues:

The key aspect here is the focus on the containment management problem independently of a a particular component implementation model (and in this context I consider A4 as a particular example of a component implementation model). By elevating the abstraction, the container implementation can handle objects that implement different component models - e.g. Avalon 4, Avalon 5, Servlet, etc.

Simplification

Something important in the above is the absence of references to things like recomposable, reconfigurable, etc. Instead, if we look at the individual artifacts that are supplied by a container to a component, and given that these artifacts are supplied based on information declared in meta-info, than "re-" aspect can be qualified relative to the artifact being applied. For example, if I declare that the component needs a logging channel, the default declaration could be that the logging channel is final - i.e. the component does not support re-assignment of the logging channel. The same concept can be applied to configuration and context related information - is contextualization final or not - are entries in a context object final or not? Are service under a service manager final or not? Same thinking in terms of entries in a service manager, etc. This allows us to eliminate completely the "re-X" approach and instead - declare this at the level of the meta-info that a component is declaring to its container.

Second interesting aspect of the above is the folding of initializable and startable under a single initialization phase. This is possible because there is no longer a particular semantic difference between a initialized and started (because the notion of re-X has been abstracted out). Decommissioning of a component is equivalent to taking a component back to its pre-initialized state where the volatile members are all of the non-final artifacts that a component type has declared.

Consider the following context meta declaration of a final (by default) context entry:

  <context> 
    <context key="urn:avalon:name"/> 
  </context> 

As opposed to the following:

  <context> 
    <context key="urn:avalon:name" final="false"/> 
  </context> 

The above statement can be interpreted as a statement by a component type that the context value for the entry "urn:avalon:name" is volatile - i.e. it can be changed at some point in the component lifecycle. Effectively, the component is declaring to the container that it is capable of handling re-deployment during which it will look for a new name value.

An alternative variation on the same theme is the declaration of a context application phase as non-final. In this case we are saying that the container has the responsibility of reapplying a context object to a component during redeployment.

  <context final="false"> 
    <context key="urn:avalon:name"/> 
  </context> 

Applicability

Within Avalon 4 we already have two variations on the sematic interpretation of the framework - the demand driven ECM / Fortress approach and the meta based Phoenix / AvalonMerlin apache. By shifting our perspective to lifecycle strategies, both approaches can be expressed as strategy implementations. It enables our ability to deal with managed an maintained versions - so instead of deprecating left right and center, we package and maintain version strategy implementations.

More broadly, strategies can be developed to address specific environments - such as Servlets - introducing 100% consistent management of components that are completely in-line with established specifications. We maintain the notions and support for component management, and we separate this from specific definition of a component through the notion of multiple strategies.

Feasibility

I've recently introduced an abstraction to context management in the avalon-sandbox/assembly package that enables a component to implement any interface for the contextualization stage. This approach can be applied to an abstract contextualization phase (covering both Avalon contextualization and servicing). The same applies to the abstract notions of logging, configuration and initialization.

One of the issues this approach brings up is the folding of the representation of contextualization and servicing into a single abstraction and the consequent impact on meta information. Work at the level of the avalon-sandbox/assembly and /meta packages is already moving closer to this goal with the simplification of dependency descriptions.

The following example declaration is basically a context declaration that captures dependency information (e.g. a Widget service with version of 2.4).

  <context final="false"> 
    <context key="urn:avalon:widget"  
      type="org.apache.avalon.playground.Widget:2.4"/> 
  </context> 

However, there is a problem with the above when dealing with an A4 strategy implementation. The problem is that the container does not have information enabling the separation of context and service information. This could be handled with a supplementary stage attribute (under a Framework 4.1 DTD) along the lines of the following example.

  <context final="false"> 
    <context key="urn:avalon:widget" stage="SERVICE" 
      type="org.apache.avalon.playground.Widget:2.4"/> 
  </context> 

Impact

Avalon 4

The impact on A4 from the client perspective would be the following:

Avalon 5

The impact on A5 from the client perspective would be the following:

Containment concerns also include:

StephenMcConnell

I think any component should be given access to its meta-info structure. Locator doesn't seem to be the right place to get it (because that meta-info is not visible to the other clients). So I would suggest to leave Contextualizable as it is.

Krage T.

AvalonFiveLifecycleProposal (last edited 2009-09-20 23:16:50 by localhost)