Developing with Cocoon is a fun and rewarding experience,
especially because it is hard write non-scalable webapps
on the platform.  Alot of this has to do with the limitations
on the developer, and forcing them to Do the Right Thing(TM).
Most of the enhancments have come out of a real need.  I
believe we have one more.

The action we have has an interface that is simple, for a
reason.  We want to be able to encourage ThreadSafe programming.
I don't ever want to lose that.  However, we have to come
to grips with the fact that not everything follows this
ideal world.

One example was that someone wanted to use an Action to obtain
a resource from a database (XML:DB to be exact), but needed
a way to release the resources at the end of the pipeline.
I think this is a reasonable request, but it does raise some
questions.

* Which pipeline?  One master pipeline that makes use of
  aggregation or the "cocoon://" protocol is made up of
  several shorter pipelines spliced together.

* How do we handle action sets?

* Should things like this be handled by a different mechanism?

So, how do we come up with a model that works?  The basic
problem restated is that we need a way of holding on to
resources for the length of the request.  After the request is
over, the resource is released.  Logically, this makes sense,
but putting something like this together is difficult in practice.

The issue actually stems from our greatest asset: components.
The very Component Based Design that Cocoon is built with affects
how things work together.  The easiest design to implement is
one that acts on immediate need.  As an analogy, I will use
memory management.

In assembly and machine language, the programmer is required to
manually set up the work areas, and perform all work within those
areas.  This is equivalent to Pre-Cocoon days where your logic,
content, and display information were all mixed together in one
resource.  It is the way you work with JSP, ASP, and ColdFusion.
We all know this is bad, and don't want to go back to those
awful working conditions if we can help it.

With the advent of higher level languages like C and C++, we
were given the blessing and curse of heap managed memory allocation.
It was great because now we didn't need to set asside work areas
ahead of time.  Sure there was a performance penalty for allowing
the OS to set up your memmory allocation and management, but it
was worth it.  If you were careful, you would allocate and deallocate
your memmory as you needed to.  The problem came when you had
to have some allocated memmory persist between scopes.  It is
easy to remember to deallocate memmory when you use it all in the
same method.  But what if you needed to hand that memmory reference
to another method--one that you may not have written?  If the
memmory was deallocated by that method your were SOL (S**t Out of
Luck--a military acronym).  This is where Cocoon is now.  If
a Component is asked for (looked up), you have to be careful to
release it--otherwise it *may* cause resource leaks.

Then cam Java and a slew of other languages that favor garbage
collection to explicit deallocation.  You have no direct control
over when a memmory area is going to be reclaimed, but you do know
it won't happen while you are still referencing it.  That means
you can pass the memmory reference around your program without
fear of it being deallocated.  This is where Cocoon needs to go.
In other words, Cocoon needs a mechanism to 1 have a reference
to a resource (Component or Object) last for an entire request.
At the end of the request, the resources are cleaned up.

So how do we design something like this without screwing our heads?
The first is to narrowly define the scope and access of these
objects.  The second is to mark these objects with an interface
so they can be handled properly.  This does require some repurposing
of the RequestContext I proposed recently.  While many people are
against using the RequestContext as a "communications" area, it is
perfectly suitable for passing object references for the life of
one request.

In order for the RequestContext to behave properly, and enforce the
contracts of mapping resouces to specific names, the put() method
must be write-once.  That means you can never overwrite a resource.
It also means that the developer needs to be smart about the resource
names he uses.  We should not impose a strict naming scheme, but offer
one that should be scalable--especially considering the Cocoon WebApp
proposal by Stefano.

One proposed naming scheme would be much like URLs:

http://infoplanning.com/schematic-access/user

Another would be a simpler form of the above version:

infoplanning.com:schematic-access/user

Still another solution would be equivalent to the
java pakage/classname solution:

com.infoplanning.schematic-access.user

Using replacement variables, the resources would be named with
these variables:

${company.domain}:${project.name}/${object.name}

This ensures that the probability of you having a unique name
within a system is high.  The developer may find that adding
one more level to the heirarchy might make sense (i.e. a
${module.name}), but it isn't necessary for most projects.

Next, we need to specify where the resource collection happens.
In order to maintain the simplest and most portable solution,
I would propose the RequestContext be managed by the Cocoon object.
That way, it is handled the same no matter what the environment
is.

Lastly, we need to provide a marker interface for resources that
must be properly released when the request is over.  Objects like
Strings, and non-pooled objects can simply have their references
nullified.  Other objects like the resources mentioned above
need a Reclaimable interface with a single method, reclaim().
For instance:

public interface Reclaimable {
    void reclaim();
}

The Reclaimable interface tells the resource to clean up after itself.
It is up to the implementor of the Reclaimable interface to decide on
the exact mechanism.  The usual method would be to store a reference
to it's pool or component manager and call put() or release() on it.
This way, Cocoon is not altered too much architecturally, and the
ComponentManager/Selectors are not altered from their purpose.  Finally,
it also means that encouraging the use of RequestContext for these types
of things encourages a consistent design and method of cleanup.

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, email: [EMAIL PROTECTED]

Reply via email to