You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cocoon.apache.org by bu...@apache.org on 2004/09/02 09:01:38 UTC

DO NOT REPLY [Bug 31012] New: - CachingPipeline validity and new IncludeTransformer

DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG 
RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT
<http://issues.apache.org/bugzilla/show_bug.cgi?id=31012>.
ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND 
INSERTED IN THE BUG DATABASE.

http://issues.apache.org/bugzilla/show_bug.cgi?id=31012

CachingPipeline validity and new IncludeTransformer

           Summary: CachingPipeline validity and new IncludeTransformer
           Product: Cocoon 2
           Version: 2.1.5
          Platform: PC
        OS/Version: Linux
            Status: NEW
          Severity: Normal
          Priority: Other
         Component: general components
        AssignedTo: dev@cocoon.apache.org
        ReportedBy: oliver.powell@tvnz.co.nz
                CC: unico@hippo.nl


This bug is related to an earlier closed bug #30356.

We are now using Unico's new
org.apache.cocoon.transformation.IncludeTransformer, which is working
fantastically for us. In a nutshell, the key feature of this new class for us is
that it 'takes on' its included source's validity as its own validity after
processing the included source/pipeline. This means the validities of included
content 'bubble up'. However, I believe this new Transformer has exposed a bug
with the way the CachingProcessingPipeline returns its validity in its
getValidityForEventPipeline method. 

The problem occurs when a pipeline that contains an IncludeTransformer step is
invoked and a valid CachedResponse is found for it. (All this action happens
primarily in the AbstractCachingProcessingPipeline class). The cached response
is validated and returned fine, but the problem is later when
getValidityForEventPipeline is called on the pipeline processing instance. 

This method fetches the validity objects from all of its cacheable components in
the pipeline (which in this case have only just been initialised but not
executed, because a cached response was found), chucks them all in an
AggregatedValidity and sends this back representing the validity of the entire
pipeline. This method is used by the SitemapSource class to set its own validity.

The problem here is that the IncludeTransformer's validity doesn't get populated
until it is executed, as naturally it doesn't know what the validity of the
included source is until is resolves it. So calling
IncludeTransformer.getValidity when it hasn't been executed (which is what
getValidityForEventPipeline does when a valid CachedResponse is found) will
always return an empty MultiSourceValidity, which is of course invalid.

Therefore, the Source validity for this pipeline will always be invalid because
the IncludeTransformer step validity is not correct.

My fix:
========
The thing is, when you have a valid CachedResponse, you actually already have
all the correct validities for the pipeline inside it. There is no need to
re-fetch them by calling getValidity on each pipeline component. So, I altered
getValidityForEventPipeline in AbstractCachingProcessingPipeline to use the
validities that were inside the CachedResponse, if one exists and is valid. The
method now looks like this:

    public SourceValidity getValidityForEventPipeline() {

        //***** This if block was added by OliverP ******
        if (this.cachedResponse != null) {

            final AggregatedValidity validity = new AggregatedValidity();
            for (int i=0; i < this.toCacheSourceValidities.length; i++) {
                validity.add(this.toCacheSourceValidities[i]);                
            }          

            if (this.getLogger().isDebugEnabled()) {
                this.getLogger().debug("OliverP: getValidityForEventPipeline:
returning cached response validity: " + validity);
            }

            return validity;

        } else {

            int vals = 0;
            
            if ( null != this.toCacheKey
                 && !this.cacheCompleteResponse 
                 && this.firstNotCacheableTransformerIndex ==
super.transformers.size()) {
                 vals = this.toCacheKey.size();
            } else if ( null != this.fromCacheKey
                         && !this.completeResponseIsCached
                         && this.firstProcessedTransformerIndex ==
super.transformers.size()) {
                 vals = this.fromCacheKey.size();
            }
            if ( vals > 0 ) {
                final AggregatedValidity validity = new AggregatedValidity();
                for(int i=0; i < vals; i++) {
                    validity.add(this.getValidityForInternalPipeline(i));
                    //validity.add(new DeferredPipelineValidity(this, i));
                }
                return validity;
            }
            return null;
        }
    }

The CachedResponse's validities have been stored in the toCacheSourceValidities
member variable. I altered the validatePipeline method in
AbstractCachingProcessingPipeline, near the end, to update this variable when it
has been determined that the CachedResponse is valid - before we lose the handle
on the CachedResponse object. This is the code block (about line #563) from the
validatePipeline method:

                if (responseIsValid) {
                    if (this.getLogger().isDebugEnabled()) {
                        this.getLogger().debug("validatePipeline: using valid
cached content for '" + environment.getURI() + "'.");
                    }
                    // we are valid, ok that's it
                    this.cachedResponse = response.getResponse();
                    this.cachedLastModified = response.getLastModified();
                    
                    //*****  Added by OliverP ***** 
                    this.toCacheSourceValidities = fromCacheValidityObjects;
                    
                } else {
                    if (this.getLogger().isDebugEnabled()) {
                        this.getLogger().debug("validatePipeline: cached content
is invalid for '" + environment.getURI() + "'.");
                    }
                    // we are not valid!
                    ......

After this, it worked great! (so far...)

I haven't got subversion going yet, so I'm not able to submit a diff format to
make these changes clearer. If anyone wants this, let me know and I'll try and
whizz one up. 

Any comments? Any pitfalls with this fix? If this is a valid bug, it would be
great if a fix could be added to the next release.

Thanks in advance,
Oliver Powell