You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cocoon.apache.org by Vadim Gritsenko <va...@reverycodes.com> on 2004/09/22 16:31:01 UTC

ThreadSafe Transformers

Y'all,

Some time ago I remember discussions about making transformers 
threadsafe, major changes, about Cocoon 3, etc. Yesterday it occured to 
me that Transformers can easily be made ThreadSafe with only additions 
to current Cocoon architecture without any major rewrites. It can be 
done in this way:

Add new interface marking threadsafe transformer:
     public interface TransformerFactory {
         Transformer getTransformer();
     }

Override select method in ComponentSelector:
     public Component select(Object hint) throws ComponentException {
         Component component = super.select(hint);
         if (this.roleId == TRANSFORMER) {
             if (component instanceof TransformerFactory) {
                 return ((TransformerFactory)component).getTransformer();
             }
         }

         return component;
     }
(it is in org.apache.cocoon.components.treeprocessor.sitemap package)

Modify existing transformer so that transformer class implements 
TransformerFactory, ThreadSafe, and nested class TransformerImpl 
implements Transformer, CacheableProcessingComponent (and it can extend 
AbstractXMLPipe). On the example of EncodeURLTransformer:
     public class EncodeURLTransformer
         implements TransformerFactory, Configurable, ThreadSafe {

         public void configure(Configuration config) {...}

         public Transformer getTransformer() {
             return new TransformerImpl();
         }

         private class TransformerImpl
             extends AbstractTransformer
             implements CacheableProcessingComponent {

             public void setup(SourceResolver resolver,
                               Map objectModel,
                               String source,
                               Parameters parameters) {...}

             public Serializable getKey() {...}

             public SourceValidity getValidity() {...}

             public void startElement(String uri,
                                      String name,
                                      String raw,
                                      Attributes attributes) {...}
             ...
         }
     }


Thus ThreadSafe transformer is a factory creating instances of SAX pipes 
performing actual transformation. Pluses of this approach, as I see it, are:
  * Transformer is <init>ed / contextualize()d / service()ed /
    configure()d / etc just once. Saves CPU cycles.
  * Transformer global configuration / context / components
    stored in single instance of ThreadSafe transformer instead
    of beeing copied in each instance of usual pooled
    transformer. Saves memory.
  * Users of ComponentSelector still receive instance of
    Transformer as they used to expect. Backward compatibility.


Now question; is it a good idea to check in this code into 2.2? Any 
drawbacks of this approach?

Thanks,
Vadim


Re: ThreadSafe Transformers

Posted by Sylvain Wallez <sy...@apache.org>.
Vadim Gritsenko wrote:

> Y'all,
>
> Some time ago I remember discussions about making transformers 
> threadsafe, major changes, about Cocoon 3, etc. Yesterday it occured 
> to me that Transformers can easily be made ThreadSafe with only 
> additions to current Cocoon architecture without any major rewrites. 
> It can be done in this way:
>
> Add new interface marking threadsafe transformer:
>     public interface TransformerFactory {
>         Transformer getTransformer();
>     }
>
> Override select method in ComponentSelector:
>     public Component select(Object hint) throws ComponentException {
>         Component component = super.select(hint);
>         if (this.roleId == TRANSFORMER) {
>             if (component instanceof TransformerFactory) {
>                 return ((TransformerFactory)component).getTransformer();
>             }
>         }
>
>         return component;
>     }
> (it is in org.apache.cocoon.components.treeprocessor.sitemap package)


Hey, nice hack!

We could even go further by having the ExtendedComponentSelector handle 
components implementing an ObjectFactory interface. That way, we 
potentially can use it for any kind of component.

<snip/>

> Now question; is it a good idea to check in this code into 2.2? Any 
> drawbacks of this approach?


I like it. The selector hack is the piece that was missing to the puzzle 
to implement it in a simple way.

Sylvain

-- 
Sylvain Wallez                                  Anyware Technologies
http://www.apache.org/~sylvain           http://www.anyware-tech.com
{ XML, Java, Cocoon, OpenSource }*{ Training, Consulting, Projects }


Re: ThreadSafe Transformers

Posted by Leo Sutic <le...@gmail.com>.
On Wed, 22 Sep 2004 11:26:22 -0400, Vadim Gritsenko
<va...@reverycodes.com> wrote:
> And keep in mind that ComponentSelector from o.a.c.c.t.sitemap is
> selector specifically for sitemap components...

Makes sense. If it's a different contract, then we can extend it as needed.

/LS

Re: ThreadSafe Transformers

Posted by Vadim Gritsenko <va...@reverycodes.com>.
Leo Sutic wrote:

> Like the idea (and we can extend it to Generators, Serializers, etc.), but:
> 
> Instinctively dislike the hack in the component selector.

Alternatively, it could be done by implementing custom ComponentHandler 
(extend DefaultComponentHandler?) from o.a.a.excalibur.component, but it 
looks more involved from whatever is described below.

And keep in mind that ComponentSelector from o.a.c.c.t.sitemap is 
selector specifically for sitemap components...

Vadim


> /LS
> 
> On Wed, 22 Sep 2004 10:31:01 -0400, Vadim Gritsenko
> <va...@reverycodes.com> wrote:
> 
>>Y'all,
>>
>>Some time ago I remember discussions about making transformers
>>threadsafe, major changes, about Cocoon 3, etc. Yesterday it occured to
>>me that Transformers can easily be made ThreadSafe with only additions
>>to current Cocoon architecture without any major rewrites. It can be
>>done in this way:
>>
>>Add new interface marking threadsafe transformer:
>>    public interface TransformerFactory {
>>        Transformer getTransformer();
>>    }
>>
>>Override select method in ComponentSelector:
>>    public Component select(Object hint) throws ComponentException {
>>        Component component = super.select(hint);
>>        if (this.roleId == TRANSFORMER) {
>>            if (component instanceof TransformerFactory) {
>>                return ((TransformerFactory)component).getTransformer();
>>            }
>>        }
>>
>>        return component;
>>    }
>>(it is in org.apache.cocoon.components.treeprocessor.sitemap package)
>>
>>Modify existing transformer so that transformer class implements
>>TransformerFactory, ThreadSafe, and nested class TransformerImpl
>>implements Transformer, CacheableProcessingComponent (and it can extend
>>AbstractXMLPipe). On the example of EncodeURLTransformer:
>>    public class EncodeURLTransformer
>>        implements TransformerFactory, Configurable, ThreadSafe {
>>
>>        public void configure(Configuration config) {...}
>>
>>        public Transformer getTransformer() {
>>            return new TransformerImpl();
>>        }
>>
>>        private class TransformerImpl
>>            extends AbstractTransformer
>>            implements CacheableProcessingComponent {
>>
>>            public void setup(SourceResolver resolver,
>>                              Map objectModel,
>>                              String source,
>>                              Parameters parameters) {...}
>>
>>            public Serializable getKey() {...}
>>
>>            public SourceValidity getValidity() {...}
>>
>>            public void startElement(String uri,
>>                                     String name,
>>                                     String raw,
>>                                     Attributes attributes) {...}
>>            ...
>>        }
>>    }
>>
>>Thus ThreadSafe transformer is a factory creating instances of SAX pipes
>>performing actual transformation. Pluses of this approach, as I see it, are:
>> * Transformer is <init>ed / contextualize()d / service()ed /
>>   configure()d / etc just once. Saves CPU cycles.
>> * Transformer global configuration / context / components
>>   stored in single instance of ThreadSafe transformer instead
>>   of beeing copied in each instance of usual pooled
>>   transformer. Saves memory.
>> * Users of ComponentSelector still receive instance of
>>   Transformer as they used to expect. Backward compatibility.
>>
>>Now question; is it a good idea to check in this code into 2.2? Any
>>drawbacks of this approach?
>>
>>Thanks,
>>Vadim


Re: ThreadSafe Transformers

Posted by Leo Sutic <le...@gmail.com>.
Like the idea (and we can extend it to Generators, Serializers, etc.), but:

Instinctively dislike the hack in the component selector.

/LS

On Wed, 22 Sep 2004 10:31:01 -0400, Vadim Gritsenko
<va...@reverycodes.com> wrote:
> Y'all,
> 
> Some time ago I remember discussions about making transformers
> threadsafe, major changes, about Cocoon 3, etc. Yesterday it occured to
> me that Transformers can easily be made ThreadSafe with only additions
> to current Cocoon architecture without any major rewrites. It can be
> done in this way:
> 
> Add new interface marking threadsafe transformer:
>     public interface TransformerFactory {
>         Transformer getTransformer();
>     }
> 
> Override select method in ComponentSelector:
>     public Component select(Object hint) throws ComponentException {
>         Component component = super.select(hint);
>         if (this.roleId == TRANSFORMER) {
>             if (component instanceof TransformerFactory) {
>                 return ((TransformerFactory)component).getTransformer();
>             }
>         }
> 
>         return component;
>     }
> (it is in org.apache.cocoon.components.treeprocessor.sitemap package)
> 
> Modify existing transformer so that transformer class implements
> TransformerFactory, ThreadSafe, and nested class TransformerImpl
> implements Transformer, CacheableProcessingComponent (and it can extend
> AbstractXMLPipe). On the example of EncodeURLTransformer:
>     public class EncodeURLTransformer
>         implements TransformerFactory, Configurable, ThreadSafe {
> 
>         public void configure(Configuration config) {...}
> 
>         public Transformer getTransformer() {
>             return new TransformerImpl();
>         }
> 
>         private class TransformerImpl
>             extends AbstractTransformer
>             implements CacheableProcessingComponent {
> 
>             public void setup(SourceResolver resolver,
>                               Map objectModel,
>                               String source,
>                               Parameters parameters) {...}
> 
>             public Serializable getKey() {...}
> 
>             public SourceValidity getValidity() {...}
> 
>             public void startElement(String uri,
>                                      String name,
>                                      String raw,
>                                      Attributes attributes) {...}
>             ...
>         }
>     }
> 
> Thus ThreadSafe transformer is a factory creating instances of SAX pipes
> performing actual transformation. Pluses of this approach, as I see it, are:
>  * Transformer is <init>ed / contextualize()d / service()ed /
>    configure()d / etc just once. Saves CPU cycles.
>  * Transformer global configuration / context / components
>    stored in single instance of ThreadSafe transformer instead
>    of beeing copied in each instance of usual pooled
>    transformer. Saves memory.
>  * Users of ComponentSelector still receive instance of
>    Transformer as they used to expect. Backward compatibility.
> 
> Now question; is it a good idea to check in this code into 2.2? Any
> drawbacks of this approach?
> 
> Thanks,
> Vadim
> 
>