cocoon-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Simone Gianni <simo...@apache.org>
Subject 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/
Date Tue, 06 Feb 2007 02:56:59 GMT
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>
>
>
>   


Mime
View raw message