cocoon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Sylvain Wallez <>
Subject Re: Cocoon Contracts (was Re: Why does Action extend ThreadSafe ?)
Date Tue, 14 Aug 2001 17:18:19 GMT

Berin Loritsch wrote:
> I have been giving _alot_ of thought about actions, components,
> and contracts in Cocoon.  Please pay attention to the different contracts
> in affect for the core components (tune in below for some comments):

Great analysis !
> 1) Action:  An action performs server side logic with _no_ display or
>    XML generation facilities.  It must be compatible with Thread Safety
>    constraints so that the majority of Actions can be ThreadSafe.
> 2) Generator: A generator performs XML generation from some external source,
>    whether it is a stream, an object, or database.  It must send SAX events
>    to the next component in a chain.  A Generator is always the first component
>    in a chain.  Due to the SAX implementation, it cannot be ThreadSafe--but
>    can be Pooled.
> 3) Transformer: A transformer recieves XML from a chain, performs some sort
>    of processing on the stream, and forwards the results to the next item in
>    a chain.  A transformer has the same issues regarding the SAX implementation,
>    and therefore has the same constraints.
> 4) Serializer: A serializer receives XML from a chain, and converts it to
>    an external stream.  A Serializer is the last element in a stream.  Again,
>    it has the same constraints placed upon it as Generator due to the same
>    issues.
> 5) Reader: A reader pulls an arbitrary resource from any source (much like a
>    Generator), but it serializes a copy to an outputstream immediately.
> 6) Matcher: A matcher tests the URI for specific patterns, and is used to
>    select specific pipelines based on requests.  A matcher _must_ be ThreadSafe,
>    and provide only simple or quick processing.

Why _must_ ? Even if matchers are likely to be more simple than actions,
the same analysis as the one you make for Action below (don't enforce
LifeStyle on work interfaces) can also apply to Matcher.

Cocoon is a powerful engine, and people will use it to build a vast
variety of applications. IMO, it's bad to put constraints like
ThreadSafe on interfaces that can have so many different and unforseen

BTW, currently neither Matcher and Selector implement ThreadSafe.

Also, a matcher can test anything in the environment, not only the URI.

> 7) Selector: A selector will test the environment for a specific set of
>    criteria and allow you to choose one or more different pipelines (or sub
>    pipelines).  Like a matcher, the selector _must_ be ThreadSafe, and provide
>    only simple or quick processing.

Same remark.

> 8) Sitemap: A sitemap will provide the overall resource to environment matching,
>             and must be ThreadSafe.
> Components with artificial constraints:
> 1) Action: Action is currently _always_ ThreadSafe.  After much thought on the
>    subject, I beleive that it is an error to enforce LifeStyle (ThreadSafe,
>    Poolable, SingleThreaded) on the work interface.  It is also an error to force
>    LifeCycle (Configurable, Contextualizable, Initializable, etc.) on the work
>    interface.  While 99% of forseen uses for Action are ThreadSafe actions, the
>    additional 1% should be possible as it causes little to no programming overhead.

Totally agree ;)

> 2) Generator: A Generator implements SitemapComponent which has two methods for
>    it's normal use.  Since a pipeline is constructed and then executed by one
>    command (generate()), setup() and generate() can theorhetically be merged for
>    a Generator.  This provides an interface much like Action--and creates the
>    ability for a ThreadSafe Generator.  This approach is prefered to forcing them
>    all to be pooled or created by factory.  This also means that a Generator cannot
>    be considered a SitemapComponent
> 3) Reader: A reader is essentially an entire pipeline in one package.  It implements
>    the SitemapComponent interface forcing it to be wither Pooled or created by factory.
>    The Reader can potentially be created in a ThreadSafe manner if the Setup(), read(),
>    and setOutputStream() methods are all merged.
> Changes that can be made:
> 1) Action:  By removing the ThreadSafe interface from the Action work interface, we
>    can allow other LifeStyles to be enforced on Actions.  This is a minor change, and
>    does not introduce complexity or violate backwards compatibility.
> Changes that cannot be made:
> 1) Generator:  We cannot easily change how Generator is made due to the API change
>    requirements.  Theorhetically we can deprecate the old generate and setup methods,
>    but that requires MethodNotImplementedException catching for the majority of cases.
> 2) Reader: Due to the same issues with Generator, we cannot make those changes due to
>    API compatibility requirements.
> Change Plan:

In which Cocoon version do you want to make the change ? IMO, this
should be available in 2.0, before the user bases grows too much. If it
is deferred to 2.1, this will make a backward incompatibility which will
require much work for users of the 2.0.

> 1) Document the current contracts in all Cocoon Components in the work interface, so
>    everyone can know the thought process for design decisions, as well as what the
>    components were designed for.
> 2) Remove the ThreadSafe interface from Action.

And add it to all implementations that currently exist so they have the
same behaviour.

> 3) Make all work interface implement an INTERFACE_VERSION constant that is filled with
>    Avalon's Version object.
> 4) Make a release with all the interface versions set to 1.0.0.
> 5) After the release, change the interface versions for Reader and Generator to 2.0.0
>    and deprecate the extra methods, providing a new method with all the information
>    combined.  This allows us to perform a quick test on INTERFACE_VERSION so that we
>    call the correct method on any one of the components.
Can you explain further how this will work ? If a component implementing
the deprecated interfaces runs inside a Cocoon with the new ones, the
interfaces version will be 2.0.0 even if the component was developped
using version 1.0.0. Or did I miss something ?

I also followed the "Interface version" thread on avalon-dev, but it
doesn't seem to be really simple...

What about some interface adapters to help people migrate 1.0.0
implementations to 2.0.0, e.g. a LegacyAbstractGenerator, that defines
the old interface as abstract methods and implements the new one by
calls to these abstract methods ?

Sylvain Wallez
Anyware Technologies -

To unsubscribe, e-mail:
For additional commands, email:

View raw message