cocoon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Sylvain Wallez <sylv...@apache.org>
Subject Re: AW: AW: Desparately seeking help with pipeline implementation
Date Mon, 01 May 2006 09:10:31 GMT
Stefan Pietschmann wrote:
> Hi Sylvain (and others),
>
> thank you for the quick response which finally helped me understand how the
> pipeline is used at runtime.
>   

Great! The main point about pipelines is that they are basically empty
shells that are filled with components by the sitemap engine, and
cleaned up after the pipeline has been executed.

They don't keep component between different requests, since the actual
components used and their parameters can change for every request, even
for the same URL.

The fact that pipelines are recyclable (i.e. poolable) is just here to
avoid having to go through the Avalon initialization stuff on each
request. Now there initialization is so simple that they actually could
be SingleThreaded rather than Recyclable and thus created anew at each
request rather than pooled.

> What I do is to throw transformers out depending on their attributes (it's a
> bit more complicated, but anyway..). Now that I see that the transformerlist
> is built anew for every request I do not need to backup the original list
> and load it everytime.

Right.

> I thought it would be built only once at the beginning.
>   

At the beginning of what? ;-)

> So my choices now are to overload the addTransformer() method, only adding a
> transformer under certain circumstances, or leave my current implementation
> which goes through this.transformers, this.transformerSources and
> this.transformerParams, checks the parameters and throws the transformers,
> sources and parameters out of the lists.
> The first way seems easier, but it means that I have to copy the whole
> method from the super class to my pipeline and change it there - I don't
> like that because you I have to check for changes with every Cocoon update.
> With the second way I can simply outsource the code going through the lists
> to my own method and call it at the beginning of setupPipeline().
>   

Why would you have to copy the superclass source code? Just call
super.addTransformer() if you need to and that's all, isn't it?

public void addTransformer(String role, String source, Parameters param,
Parameters hintParam) {
    if (keepTransformer(role, source, params, hintParam) {
        super.addTransformer(role, source, params, hintParam);
    }
}

Another option, if you need to do some complex computation on the
transformer list is to overload setSerializer(). When this method is
called, all transformers in the pipeline are there.

> I do have one more question - to make it right this time. If I prevent a
> transformer from being added to the list in addTransformer(), or if I kick
> it out in my method, I see I have to release it.

Yes.

> This is done by the following in AbstractProcessingPipeline:
>
> int size = this.transformerSelectors.size();
> for (int i = 0; i < size; i++) {
>   final ComponentSelector selector = (ComponentSelector)
> this.transformerSelectors.get(i);
>   selector.release((Component) this.transformers.get(i));
>   this.newManager.release(selector);
> }
>
> In my method it would look like:
>
> Iterator transformerItt = this.transformers.iterator();
> ...
> int i = 0;
> while (transformerItt.hasNext()) {
>       Transformer trans = (Transformer) transformerItt.next();
> 	...
> 	// check if the transformer should be run
> 	..
> 	// kick it out
>       transformerItt.remove();
> 	// release transformer
> 	final ComponentSelector selector = (ComponentSelector)
> this.transformerSelectors.get(i);
> 	  selector.release((Component) trans);
> 	this.newManager.release(selector);
> 	i++;
> }     
>
> Right?
>   

That's the idea, but you have some bugs here since when you remove a
transformer, you should also remove the corresponding selector and
parameters:

for (int i = 0; i < this.transformers.size(); /* do not increment here */) {
    if (trashTransformerAt(i)) {
        // Release what needs to be
        Transformer transf = (Transformer)this.transformers.get(i);
        ComponentSelector selector =
(ComponentSelector)this.transformerSelectors.get(i);
        selector.release(transf);
        this.newManager.release(selector);

        // Update lists
        this.transformers.remove(i);
        this.transformerSelectors.remove(i);
        this.transformerParams.remove(i);
        this.transformerSources.remove(i);
    } else {
        i++;
    }
}

Be careful also that depending on the class you extend, there are a
couple of other lists to update as well:
- transformerRoles in AbstractCachingProcessingPipeline
- isCachePoint in CachingPointPipeline

Sylvain

-- 
Sylvain Wallez - http://bluxte.net


Mime
View raw message