You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cocoon.apache.org by Simone Gianni <si...@apache.org> on 2007/02/06 03:56:59 UTC

Re: svn commit: r503964 - in /cocoon/trunk/blocks/cocoon-profiler/cocoon-profiler-impl/src/main: java/org/apache/cocoon/components/profiler/ resources/META-INF/cocoon/avalon/

Hi all,
I was playing with the profiler when I noticed the way the
ProfilingXMLPipe works. Every component is given the opportunity to
stream its sax events, they are buffered in a DOM, the DOM is then used
(to display the intermediate XML and) to stream SAX events to the next
component. This behavior is different from how a pipeline normally
works, and can cause strange errors (or mask errors that will appear
when the profiler is removed).

So I implemented another class, the ProfilingSAXPipe, that does all the
ProfilingXMLPipe does, but stream the sax events directly, without
storing them in a DOM and doing it step by step. Time calculation is
obviously more complicated, and I'm not yet sure it's precise enough,
but seems to be consistent with the default implementation.

To activate it pass a sax-stream="true" on the pipeline definition, or
use the profile-caching-sax and profile-noncaching-sax pipeline types.

Can someone point me to the right documentation branch where I should
update documentation?

Simone

simoneg@apache.org wrote:
> Author: simoneg
> Date: Mon Feb  5 18:46:03 2007
> New Revision: 503964
>
> URL: http://svn.apache.org/viewvc?view=rev&rev=503964
> Log:
> Added another implemetation of profiling pipe respecting the sax streaming contract
>
> Added:
>     cocoon/trunk/blocks/cocoon-profiler/cocoon-profiler-impl/src/main/java/org/apache/cocoon/components/profiler/ProfilingSAXPipe.java
> Modified:
>     cocoon/trunk/blocks/cocoon-profiler/cocoon-profiler-impl/src/main/java/org/apache/cocoon/components/profiler/ProfilingCachingProcessingPipeline.java
>     cocoon/trunk/blocks/cocoon-profiler/cocoon-profiler-impl/src/main/java/org/apache/cocoon/components/profiler/ProfilingNonCachingProcessingPipeline.java
>     cocoon/trunk/blocks/cocoon-profiler/cocoon-profiler-impl/src/main/resources/META-INF/cocoon/avalon/cocoon-profiler-sitemap.xconf
>
> Modified: cocoon/trunk/blocks/cocoon-profiler/cocoon-profiler-impl/src/main/java/org/apache/cocoon/components/profiler/ProfilingCachingProcessingPipeline.java
> URL: http://svn.apache.org/viewvc/cocoon/trunk/blocks/cocoon-profiler/cocoon-profiler-impl/src/main/java/org/apache/cocoon/components/profiler/ProfilingCachingProcessingPipeline.java?view=diff&rev=503964&r1=503963&r2=503964
> ==============================================================================
> --- cocoon/trunk/blocks/cocoon-profiler/cocoon-profiler-impl/src/main/java/org/apache/cocoon/components/profiler/ProfilingCachingProcessingPipeline.java (original)
> +++ cocoon/trunk/blocks/cocoon-profiler/cocoon-profiler-impl/src/main/java/org/apache/cocoon/components/profiler/ProfilingCachingProcessingPipeline.java Mon Feb  5 18:46:03 2007
> @@ -18,6 +18,9 @@
>  
>  import java.util.Iterator;
>  
> +import org.apache.avalon.framework.configuration.Configurable;
> +import org.apache.avalon.framework.configuration.Configuration;
> +import org.apache.avalon.framework.configuration.ConfigurationException;
>  import org.apache.avalon.framework.parameters.Parameters;
>  import org.apache.avalon.framework.service.ServiceException;
>  import org.apache.avalon.framework.service.ServiceManager;
> @@ -27,13 +30,14 @@
>  import org.apache.cocoon.sitemap.SitemapModelComponent;
>  import org.apache.cocoon.transformation.Transformer;
>  import org.apache.cocoon.xml.XMLConsumer;
> +import org.apache.cocoon.xml.XMLPipe;
>  import org.apache.cocoon.xml.XMLProducer;
>  
>  /**
>   * @version $Id$
>   */
>  public class ProfilingCachingProcessingPipeline
> -    extends CachingProcessingPipeline {
> +	extends CachingProcessingPipeline implements Configurable {
>  
>      private Profiler profiler;
>  
> @@ -41,6 +45,8 @@
>  
>      private int index;
>  
> +	private boolean saxstream = false;
> +
>      /**
>       * @see org.apache.cocoon.components.pipeline.AbstractProcessingPipeline#service(org.apache.avalon.framework.service.ServiceManager)
>       */
> @@ -48,6 +54,11 @@
>          super.service(aManager);
>          this.profiler = (Profiler) manager.lookup(Profiler.ROLE);
>      }
> +    
> +	public void configure(Configuration conf) throws ConfigurationException {
> +		this.saxstream  = conf.getAttributeAsBoolean("sax-stream", false);
> +	}    
> +    
>  
>      /**
>       * @see org.apache.cocoon.components.pipeline.impl.BaseCachingProcessingPipeline#dispose()
> @@ -298,10 +309,18 @@
>      protected void connect(Environment environment, XMLProducer producer,
>                             XMLConsumer consumer)
>      throws ProcessingException {
> -        ProfilingXMLPipe connector = new ProfilingXMLPipe();
> -        connector.setup(this.index, this.data);
> +    	XMLPipe pipe = null;
> +    	if (saxstream) {
> +	        ProfilingSAXPipe connector = new ProfilingSAXPipe();
> +	        connector.setup(this.index, this.data);
> +	        pipe = connector;    		
> +    	} else {
> +	        ProfilingXMLPipe connector = new ProfilingXMLPipe();
> +	        connector.setup(this.index, this.data);
> +	        pipe = connector;
> +    	}
>          this.index++;
> -        super.connect(environment, producer, connector);
> -        super.connect(environment, connector, consumer);
> +        super.connect(environment, producer, pipe);
> +        super.connect(environment, pipe, consumer);
>      }
>  }
>
> Modified: cocoon/trunk/blocks/cocoon-profiler/cocoon-profiler-impl/src/main/java/org/apache/cocoon/components/profiler/ProfilingNonCachingProcessingPipeline.java
> URL: http://svn.apache.org/viewvc/cocoon/trunk/blocks/cocoon-profiler/cocoon-profiler-impl/src/main/java/org/apache/cocoon/components/profiler/ProfilingNonCachingProcessingPipeline.java?view=diff&rev=503964&r1=503963&r2=503964
> ==============================================================================
> --- cocoon/trunk/blocks/cocoon-profiler/cocoon-profiler-impl/src/main/java/org/apache/cocoon/components/profiler/ProfilingNonCachingProcessingPipeline.java (original)
> +++ cocoon/trunk/blocks/cocoon-profiler/cocoon-profiler-impl/src/main/java/org/apache/cocoon/components/profiler/ProfilingNonCachingProcessingPipeline.java Mon Feb  5 18:46:03 2007
> @@ -19,6 +19,9 @@
>  import java.util.Iterator;
>  
>  import org.apache.avalon.framework.activity.Disposable;
> +import org.apache.avalon.framework.configuration.Configurable;
> +import org.apache.avalon.framework.configuration.Configuration;
> +import org.apache.avalon.framework.configuration.ConfigurationException;
>  import org.apache.avalon.framework.parameters.Parameters;
>  import org.apache.avalon.framework.service.ServiceException;
>  import org.apache.avalon.framework.service.ServiceManager;
> @@ -28,6 +31,7 @@
>  import org.apache.cocoon.sitemap.SitemapModelComponent;
>  import org.apache.cocoon.transformation.Transformer;
>  import org.apache.cocoon.xml.XMLConsumer;
> +import org.apache.cocoon.xml.XMLPipe;
>  import org.apache.cocoon.xml.XMLProducer;
>  
>  /**
> @@ -38,13 +42,15 @@
>   * @version $Id$
>   */
>  public class ProfilingNonCachingProcessingPipeline extends NonCachingProcessingPipeline
> -                                                   implements Disposable {
> +                                                   implements Disposable, Configurable {
>  
>      private Profiler profiler;
>  
>      private ProfilerData data;
>  
>      private int index;
> +    
> +    private boolean saxstream = false;
>  
>      /**
>       * @see org.apache.cocoon.components.pipeline.AbstractProcessingPipeline#service(org.apache.avalon.framework.service.ServiceManager)
> @@ -54,6 +60,10 @@
>          this.profiler = (Profiler) manager.lookup(Profiler.ROLE);
>      }
>  
> +	public void configure(Configuration conf) throws ConfigurationException {
> +		this.saxstream = conf.getAttributeAsBoolean("sax-stream", false);
> +	}    
> +    
>      /**
>       * @see org.apache.avalon.framework.activity.Disposable#dispose()
>       */
> @@ -295,12 +305,19 @@
>       */
>      protected void connect(Environment environment, XMLProducer producer,
>                             XMLConsumer consumer) throws ProcessingException {
> -        ProfilingXMLPipe connector = new ProfilingXMLPipe();
> -
> -        connector.setup(this.index, this.data);
> +    	XMLPipe pipe = null;
> +    	if (saxstream) {
> +	        ProfilingSAXPipe connector = new ProfilingSAXPipe();
> +	        connector.setup(this.index, this.data);
> +	        pipe = connector;    		
> +    	} else {
> +	        ProfilingXMLPipe connector = new ProfilingXMLPipe();
> +	        connector.setup(this.index, this.data);
> +	        pipe = connector;
> +    	}
>          this.index++;
> -        super.connect(environment, producer, connector);
> -        super.connect(environment, connector, consumer);
> +        super.connect(environment, producer, pipe);
> +        super.connect(environment, pipe, consumer);
>      }
>  
>  }
>
> Added: cocoon/trunk/blocks/cocoon-profiler/cocoon-profiler-impl/src/main/java/org/apache/cocoon/components/profiler/ProfilingSAXPipe.java
> URL: http://svn.apache.org/viewvc/cocoon/trunk/blocks/cocoon-profiler/cocoon-profiler-impl/src/main/java/org/apache/cocoon/components/profiler/ProfilingSAXPipe.java?view=auto&rev=503964
> ==============================================================================
> --- cocoon/trunk/blocks/cocoon-profiler/cocoon-profiler-impl/src/main/java/org/apache/cocoon/components/profiler/ProfilingSAXPipe.java (added)
> +++ cocoon/trunk/blocks/cocoon-profiler/cocoon-profiler-impl/src/main/java/org/apache/cocoon/components/profiler/ProfilingSAXPipe.java Mon Feb  5 18:46:03 2007
> @@ -0,0 +1,219 @@
> +package org.apache.cocoon.components.profiler;
> +
> +import java.util.Map;
> +import java.util.WeakHashMap;
> +
> +import org.apache.cocoon.components.sax.XMLByteStreamCompiler;
> +import org.apache.cocoon.xml.XMLConsumer;
> +import org.apache.cocoon.xml.XMLPipe;
> +import org.xml.sax.Attributes;
> +import org.xml.sax.Locator;
> +import org.xml.sax.SAXException;
> +
> +public class ProfilingSAXPipe implements XMLPipe {
> +
> +	private static Map pipes = new WeakHashMap();
> +	
> +    private XMLConsumer consumer;
> +
> +    // Data of the profile
> +    private ProfilerData data;
> +
> +    // Index of the component
> +    private int index;
> +
> +    // Start time
> +    private long time;
> +    private boolean inside = false;
> +
> +    // Time difference
> +    private long total;
> +
> +    private XMLByteStreamCompiler serializer;
> +
> +    /**
> +     * Setup this XMLPipe.
> +     *
> +     * @param index Index of the component.
> +     * @param data Data of the profile.
> +     */
> +    public void setup(int index, ProfilerData data) {
> +        this.index = index;
> +        this.data = data;
> +        this.serializer = new XMLByteStreamCompiler();
> +    }
> +
> +    /**
> +     * Set the <code>XMLConsumer</code> that will receive XML data.
> +     */
> +    public void setConsumer(XMLConsumer consumer) {
> +        this.consumer = consumer;
> +    }
> +
> +    private void entered() {
> +    	assert(!this.inside);
> +    	ProfilingSAXPipe other = (ProfilingSAXPipe) pipes.get(this.data);
> +    	assert(other != null);
> +    	if (other != this) other.exited();
> +    	this.inside = true;
> +    	this.time = System.currentTimeMillis();
> +    }
> +    
> +    private void exited() {
> +    	long current = System.currentTimeMillis();
> +    	if (!this.inside) {
> +        	ProfilingSAXPipe other = (ProfilingSAXPipe) pipes.get(this.data);
> +    		if (other != null) {
> +    			this.time = other.getTime();
> +    		} else {
> +    			this.time = current;
> +    		}
> +    	}
> +    	this.total += current - this.time;
> +    	this.time = current;
> +    	pipes.put(this.data, this);
> +    }
> +    
> +    public void startDocument() throws SAXException {
> +    	exited();
> +        this.serializer.startDocument();
> +        this.consumer.startDocument();
> +        entered();
> +    }
> +
> +    public void endDocument() throws SAXException {
> +    	exited();
> +        this.serializer.endDocument();
> +        this.consumer.endDocument();
> +        
> +        if (this.index != -1)
> +            this.data.setProcessingTime(this.index, this.total);
> +
> +        // push the content of the buffer through the next component
> +        Object fragment = this.serializer.getSAXFragment();
> +
> +        if (this.index != -1)
> +            this.data.setSAXFragment(this.index, fragment);
> +    }
> +
> +    public void setDocumentLocator(Locator locator) {
> +    	exited();
> +        this.serializer.setDocumentLocator(locator);
> +        this.consumer.setDocumentLocator(locator);
> +        entered();
> +    }
> +
> +    public void startPrefixMapping(String prefix, String uri) throws SAXException {
> +    	exited();
> +        this.serializer.startPrefixMapping(prefix, uri);
> +        this.consumer.startPrefixMapping(prefix, uri);
> +        entered();
> +    }
> +
> +    public void endPrefixMapping(String prefix) throws SAXException {
> +    	exited();
> +        this.serializer.endPrefixMapping(prefix);
> +        this.consumer.endPrefixMapping(prefix);
> +        entered();
> +    }
> +
> +    public void startElement(String uri, String loc, String raw, Attributes a) throws SAXException {
> +    	exited();
> +        this.serializer.startElement(uri, loc, raw, a);
> +        this.consumer.startElement(uri, loc, raw, a);
> +        entered();
> +    }
> +
> +    public void endElement(String uri, String loc, String raw) throws SAXException {
> +    	exited();
> +        this.serializer.endElement(uri, loc, raw);
> +        this.consumer.endElement(uri, loc, raw);
> +        entered();
> +    }
> +
> +    public void characters(char c[], int start, int len) throws SAXException {
> +    	exited();
> +        this.serializer.characters(c, start, len);
> +        this.consumer.characters(c, start, len);
> +        entered();
> +    }
> +
> +    public void ignorableWhitespace(char c[], int start, int len) throws SAXException {
> +    	exited();
> +        this.serializer.ignorableWhitespace(c, start, len);
> +        this.consumer.ignorableWhitespace(c, start, len);
> +        entered();
> +    }
> +
> +    public void processingInstruction(String target, String data) throws SAXException {
> +    	exited();
> +        this.serializer.processingInstruction(target, data);
> +        this.consumer.processingInstruction(target, data);
> +        entered();
> +    }
> +
> +    public void skippedEntity(String name) throws SAXException {
> +    	exited();
> +        this.serializer.skippedEntity(name);
> +        this.consumer.skippedEntity(name);
> +        entered();
> +    }
> +
> +    public void startDTD(String name, String publicId, String systemId) throws SAXException {
> +    	exited();
> +        this.serializer.startDTD(name, publicId, systemId);
> +        this.consumer.startDTD(name, publicId, systemId);
> +        entered();
> +    }
> +
> +    public void endDTD() throws SAXException {
> +    	exited();
> +        this.serializer.endDTD();
> +        this.consumer.endDTD();
> +        entered();
> +    }
> +
> +    public void startEntity(String name) throws SAXException {
> +    	exited();
> +        this.serializer.startEntity(name);
> +        this.consumer.startEntity(name);
> +        entered();
> +    }
> +
> +    public void endEntity(String name) throws SAXException {
> +    	exited();
> +        this.serializer.endEntity(name);
> +        this.consumer.endEntity(name);
> +        entered();
> +    }
> +
> +    public void startCDATA() throws SAXException {
> +    	exited();
> +        this.serializer.startCDATA();
> +        this.consumer.startCDATA();
> +        entered();
> +    }
> +
> +    public void endCDATA() throws SAXException {
> +    	exited();
> +        this.serializer.endCDATA();
> +        this.consumer.endCDATA();
> +        entered();
> +    }
> +
> +    public void comment(char ch[], int start, int len) throws SAXException {
> +    	exited();
> +        this.serializer.comment(ch, start, len);
> +        this.consumer.comment(ch, start, len);
> +        entered();
> +    }
> +
> +	public boolean isInside() {
> +		return inside;
> +	}
> +
> +	public long getTime() {
> +		return time;
> +	}	
> +
> +}
>
> Modified: cocoon/trunk/blocks/cocoon-profiler/cocoon-profiler-impl/src/main/resources/META-INF/cocoon/avalon/cocoon-profiler-sitemap.xconf
> URL: http://svn.apache.org/viewvc/cocoon/trunk/blocks/cocoon-profiler/cocoon-profiler-impl/src/main/resources/META-INF/cocoon/avalon/cocoon-profiler-sitemap.xconf?view=diff&rev=503964&r1=503963&r2=503964
> ==============================================================================
> --- cocoon/trunk/blocks/cocoon-profiler/cocoon-profiler-impl/src/main/resources/META-INF/cocoon/avalon/cocoon-profiler-sitemap.xconf (original)
> +++ cocoon/trunk/blocks/cocoon-profiler/cocoon-profiler-impl/src/main/resources/META-INF/cocoon/avalon/cocoon-profiler-sitemap.xconf Mon Feb  5 18:46:03 2007
> @@ -32,5 +32,9 @@
>                     src="org.apache.cocoon.components.profiler.ProfilingCachingProcessingPipeline"/>
>       <map:pipe name="profile-noncaching"
>                     src="org.apache.cocoon.components.profiler.ProfilingNonCachingProcessingPipeline"/>
> +     <map:pipe name="profile-caching-sax"
> +                   src="org.apache.cocoon.components.profiler.ProfilingCachingProcessingPipeline" sax-stream="true"/>
> +     <map:pipe name="profile-noncaching-sax"
> +                   src="org.apache.cocoon.components.profiler.ProfilingNonCachingProcessingPipeline" sax-stream="true"/>
>    </map:pipes>
>  </map:components>
>
>
>   


Re: Block Docs

Posted by Vadim Gritsenko <va...@reverycodes.com>.
Reinhard Poetz wrote:
> Vadim Gritsenko wrote:
>> Simone Gianni wrote:
>>> Can someone point me to the right documentation branch where I should
>>> update documentation?
>>
>> I'd guess it should be "cdocs: Profiler Block", but it is not listed on:
>>
>> Not sure how easy/hard it is to add it there... Reinhard?
> 
> It takes you about 15 minutes ...

Thanks. Simone - you can edit/add profiler docos here:

   http://cocoon.zones.apache.org/daisy/cdocs-profiler/g1/1322.html

Vadim

Re: Block Docs

Posted by Reinhard Poetz <re...@apache.org>.
Vadim Gritsenko wrote:
> Simone Gianni wrote:
>> Can someone point me to the right documentation branch where I should
>> update documentation?
> 
> I'd guess it should be "cdocs: Profiler Block", but it is not listed on:
> 
>   http://cocoon.zones.apache.org/daisy/
> 
> Not sure how easy/hard it is to add it there... Reinhard?

It takes you about 15 minutes and you need to be part of the suduers list of our 
zone, see http://cocoon.zones.apache.org/daisy/cdocs/g3/1223.html

If you want to be able to build the docs locally, see 
http://cocoon.zones.apache.org/daisy/cdocs/g3/1256.html. Takes you another 5 
minutes and about 8 minutes for the actual build process.

-- 
Reinhard Pötz           Independent Consultant, Trainer & (IT)-Coach 

{Software Engineering, Open Source, Web Applications, Apache Cocoon}

                                        web(log): http://www.poetz.cc
--------------------------------------------------------------------

Block Docs, Re: svn commit: r503964 - in /cocoon/trunk/blocks/cocoon-profiler/cocoon-profiler-impl/src/main: java/org/apache/cocoon/components/profiler/ resources/META-INF/cocoon/avalon/

Posted by Vadim Gritsenko <va...@reverycodes.com>.
Simone Gianni wrote:
> Hi all,
> I was playing with the profiler when I noticed the way the
> ProfilingXMLPipe works. Every component is given the opportunity to
> stream its sax events, they are buffered in a DOM, the DOM is then used
> (to display the intermediate XML and) to stream SAX events to the next
> component. This behavior is different from how a pipeline normally
> works, and can cause strange errors (or mask errors that will appear
> when the profiler is removed).
> 
> So I implemented another class, the ProfilingSAXPipe, that does all the
> ProfilingXMLPipe does, but stream the sax events directly, without
> storing them in a DOM and doing it step by step. Time calculation is
> obviously more complicated, and I'm not yet sure it's precise enough,
> but seems to be consistent with the default implementation.
> 
> To activate it pass a sax-stream="true" on the pipeline definition, or
> use the profile-caching-sax and profile-noncaching-sax pipeline types.
> 
> Can someone point me to the right documentation branch where I should
> update documentation?

I'd guess it should be "cdocs: Profiler Block", but it is not listed on:

   http://cocoon.zones.apache.org/daisy/

Not sure how easy/hard it is to add it there... Reinhard?

Vadim

> Simone
> 
> simoneg@apache.org wrote:
>> Author: simoneg
>> Date: Mon Feb  5 18:46:03 2007
>> New Revision: 503964
>>
>> URL: http://svn.apache.org/viewvc?view=rev&rev=503964
>> Log:
>> Added another implemetation of profiling pipe respecting the sax streaming contract