You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@cocoon.apache.org by un...@apache.org on 2004/03/24 16:19:20 UTC

cvs commit: cocoon-2.1/src/blocks/scratchpad/java/org/apache/cocoon/components/source/impl CachedSourceResponse.java CachingSource.java TraversableCachingSource.java UpdateTarget.java

unico       2004/03/24 07:19:20

  Modified:    src/blocks/scratchpad/java/org/apache/cocoon/components/source/impl
                        CachedSourceResponse.java CachingSource.java
                        TraversableCachingSource.java UpdateTarget.java
  Log:
  Only update cache if source is actually invalid;
  Don't store response if expires = 0
  Add more debugging and improve documentation.
  
  Revision  Changes    Path
  1.2       +2 -2      cocoon-2.1/src/blocks/scratchpad/java/org/apache/cocoon/components/source/impl/CachedSourceResponse.java
  
  Index: CachedSourceResponse.java
  ===================================================================
  RCS file: /home/cvs/cocoon-2.1/src/blocks/scratchpad/java/org/apache/cocoon/components/source/impl/CachedSourceResponse.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- CachedSourceResponse.java	22 Mar 2004 17:38:25 -0000	1.1
  +++ CachedSourceResponse.java	24 Mar 2004 15:19:20 -0000	1.2
  @@ -30,8 +30,8 @@
       private byte[] m_xml;
       private Serializable m_extra;
       
  -    public CachedSourceResponse(SourceValidity validity) {
  -        super(validity, null);
  +    public CachedSourceResponse(SourceValidity[] validities) {
  +        super(validities, null);
       }
       
       public byte[] getBinaryResponse() {
  
  
  
  1.9       +105 -22   cocoon-2.1/src/blocks/scratchpad/java/org/apache/cocoon/components/source/impl/CachingSource.java
  
  Index: CachingSource.java
  ===================================================================
  RCS file: /home/cvs/cocoon-2.1/src/blocks/scratchpad/java/org/apache/cocoon/components/source/impl/CachingSource.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- CachingSource.java	23 Mar 2004 16:28:54 -0000	1.8
  +++ CachingSource.java	24 Mar 2004 15:19:20 -0000	1.9
  @@ -57,7 +57,7 @@
    * 
    * <h2>Syntax for Protocol</h2>
    * <p>
  - * cached:http://www.apache.org[?cocoon:cache-expires=60&cocoon:cache-name=main]
  + * cached:http://www.apache.org/[?cocoon:cache-expires=60&cocoon:cache-name=main]
    * </p>
    * <p>
    * The above examples show how the real source <code>http://www.apache.org</code>
  @@ -150,14 +150,69 @@
        * Initialize the Source.
        */
       public void initialize() throws Exception {
  +        
  +        boolean checkValidity = true;
  +        if (this.expires == -1) {
  +            if (getLogger().isDebugEnabled()) {
  +                getLogger().debug("Using cached response if available.");
  +            }
  +            checkValidity = false;
  +        }
  +        
  +        if (this.async && this.expires != 0) {
  +            if (getLogger().isDebugEnabled()) {
  +                getLogger().debug("Not invalidating cached response " +
                    "for asynch source " + getSourceURI());
  +            }
  +            checkValidity = false;
  +        }
  +
           this.response = (CachedSourceResponse) this.cache.get(this.cacheKey);
  -        if (this.response != null && (!this.async || expires == 0)) {
  -            // check if the source is cached, throw it out if invalid
  -            final SourceValidity validity = this.response.getValidityObjects()[0];
  -            if (expires != -1 && (expires == 0 || validity.isValid() != SourceValidity.VALID)) {
  +        if (this.response == null) {
  +            if (getLogger().isDebugEnabled()) {
  +                getLogger().debug("No cached response found " +
                    "for source " + getSourceURI());
  +            }
  +            checkValidity = false;
  +        }
  +        
  +        if (checkValidity) {
  +            
  +            final ExpiresValidity cacheValidity = (ExpiresValidity) this.response.getValidityObjects()[0];
  +            final SourceValidity sourceValidity = this.response.getValidityObjects()[1];
  +            
  +            boolean remove = false;
  +            if (this.expires == 0) {
                   if (getLogger().isDebugEnabled()) {
  -                    getLogger().debug("Invalid cached response for source " + getSourceURI());
  +                    getLogger().debug("Force invalidation of cached response" +
                        " of source " + getSourceURI());
                   }
  +                remove = true;
  +            }
  +            else {
  +                boolean expired = cacheValidity.isValid() != SourceValidity.VALID;
  +                if (expired) {
  +                    if (getLogger().isDebugEnabled()) {
  +                        getLogger().debug("Cached response of source " 
  +                            + getSourceURI() + " is expired.");
  +                    }
  +                    boolean invalid = !isValid(sourceValidity, this.source);
  +                    if (invalid) {
  +                        if (getLogger().isDebugEnabled()) {
  +                            getLogger().debug("Cached response of source "
  +                                + getSourceURI() + " is invalid.");
  +                        }
  +                        remove = true;
  +                    }
  +                    else {
  +                        if (getLogger().isDebugEnabled()) {
  +                            getLogger().debug("Cached response of source " 
  +                                + getSourceURI() + " is still valid.");
  +                        }
  +                        // set new expiration period
  +                        this.response.getValidityObjects()[0] = new ExpiresValidity(getExpiration());
  +                    }
  +                }
  +            }
  +            
  +            if (remove) {
                   this.response = null;
                   // remove it if it no longer exists
                   if (!exists()) {
  @@ -165,7 +220,7 @@
                   }
               }
           }
  -        if (this.async && expires > 0) {
  +        if (this.async && this.expires > 0) {
               // schedule it with the refresher
               this.refresher.refresh(this.cacheKey,
                                      getSourceURI(),
  @@ -193,14 +248,21 @@
        * @param refresh  whether to force refresh
        * @throws IOException  if an the binary response could not be initialized
        */
  -    protected void initMetaResponse(boolean refresh) throws IOException {
  +    protected void initMetaResponse() throws IOException {
           boolean storeResponse = false;
           CachedSourceResponse response = this.response;
           if (response == null) {
  -            response = new CachedSourceResponse(new ExpiresValidity(getExpiration()));
  -            storeResponse = true;
  +            if (this.expires != 0) {
  +                final SourceValidity cacheValidity = new ExpiresValidity(getExpiration());
  +                final SourceValidity sourceValidity = source.getValidity();
  +                response = new CachedSourceResponse(new SourceValidity[] {cacheValidity, sourceValidity});
  +                storeResponse = true;
  +            }
  +            else {
  +                response = new CachedSourceResponse(null);
  +            }
           }
  -        if (response.getExtra() == null || refresh) {
  +        if (response.getExtra() == null) {
               response.setExtra(readMeta(this.source));
               this.freshMeta = true;
           }
  @@ -221,15 +283,22 @@
        * @param refresh  whether to force refresh
        * @throws IOException  if an the binary response could not be initialized
        */
  -    protected void initBinaryResponse(boolean refresh) throws IOException {
  +    protected void initBinaryResponse() throws IOException {
           boolean storeResponse = false;
           /* delay caching the response until we have a valid new one */
           CachedSourceResponse response = this.response;
           if (response == null) {
  -            response = new CachedSourceResponse(new ExpiresValidity(getExpiration()));
  -            storeResponse = true;
  +            if (this.expires != 0) {
  +                final SourceValidity cacheValidity = new ExpiresValidity(getExpiration());
  +                final SourceValidity sourceValidity = source.getValidity();
  +                response = new CachedSourceResponse(new SourceValidity[] {cacheValidity, sourceValidity});
  +                storeResponse = true;
  +            }
  +            else {
  +                response = new CachedSourceResponse(null);
  +            }
           }
  -        if (response.getBinaryResponse() == null || refresh) {
  +        if (response.getBinaryResponse() == null) {
               response.setBinaryResponse(readBinaryResponse(this.source));
               if (!this.freshMeta) {
                   /* always refresh meta in this case */
  @@ -260,8 +329,15 @@
           /* delay caching the response until we have a valid new one */
           CachedSourceResponse response = this.response;
           if (response == null) {
  -            response = new CachedSourceResponse(new ExpiresValidity(getExpiration()));
  -            storeResponse = true;
  +            if (this.expires != 0) {
  +                final SourceValidity cacheValidity = new ExpiresValidity(getExpiration());
  +                final SourceValidity sourceValidity = source.getValidity();
  +                response = new CachedSourceResponse(new SourceValidity[] {cacheValidity, sourceValidity});
  +                storeResponse = true;
  +            }
  +            else {
  +                response = new CachedSourceResponse(null);
  +            }
           }
           if (response.getXMLResponse() == null || refresh) {
               byte[] binary = response.getBinaryResponse();
  @@ -306,7 +382,7 @@
        */
       public long getLastModified() {
           try {
  -            initMetaResponse(false);
  +            initMetaResponse();
           } catch (IOException io) {
               return 0;
           }
  @@ -320,7 +396,7 @@
        */
       public String getMimeType() {
           try {
  -            initMetaResponse(false);
  +            initMetaResponse();
           } catch (IOException io) {
               return null;
           }
  @@ -332,7 +408,7 @@
        */
       public InputStream getInputStream() throws IOException, SourceException {
           try {
  -            initBinaryResponse(false);
  +            initBinaryResponse();
           } catch (IOException se) {
               throw new SourceException("Failure getting input stream", se);
           }
  @@ -425,7 +501,7 @@
       protected long getExpiration() {
           return this.expires * 1000;
       }
  -        
  +    
       /**
        * Read XML content from source.
        * 
  @@ -537,6 +613,13 @@
           meta.setMimeType(source.getMimeType());
           
           return meta;
  +    }
  +    
  +    protected static boolean isValid(SourceValidity validity, Source source) {
  +        if (validity == null) return false;
  +        return validity.isValid() == SourceValidity.VALID || 
  +              (validity.isValid() == SourceValidity.UNKNOWN && 
  +               validity.isValid(source.getValidity()) == SourceValidity.VALID);
       }
       
       /**
  
  
  
  1.4       +5 -5      cocoon-2.1/src/blocks/scratchpad/java/org/apache/cocoon/components/source/impl/TraversableCachingSource.java
  
  Index: TraversableCachingSource.java
  ===================================================================
  RCS file: /home/cvs/cocoon-2.1/src/blocks/scratchpad/java/org/apache/cocoon/components/source/impl/TraversableCachingSource.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- TraversableCachingSource.java	23 Mar 2004 16:28:54 -0000	1.3
  +++ TraversableCachingSource.java	24 Mar 2004 15:19:20 -0000	1.4
  @@ -47,7 +47,7 @@
       public String getName() {
           
           try {
  -            initMetaResponse(false);
  +            initMetaResponse();
           }
           catch (IOException e) {
               if (getLogger().isDebugEnabled()) {
  @@ -62,7 +62,7 @@
       public boolean isCollection() {
           
           try {
  -            initMetaResponse(false);
  +            initMetaResponse();
           }
           catch (IOException e) {
               if (getLogger().isDebugEnabled()) {
  @@ -78,7 +78,7 @@
           
           Source child;
           try {
  -            initMetaResponse(false);
  +            initMetaResponse();
               child = this.tsource.getChild(name);
           }
           catch (SourceException e) {
  @@ -98,7 +98,7 @@
       public Collection getChildren() throws SourceException {
           
           try {
  -            initMetaResponse(false);
  +            initMetaResponse();
           }
           catch (SourceException e) {
               throw e;
  @@ -132,7 +132,7 @@
           
           Source parent;
           try {
  -            initMetaResponse(false);
  +            initMetaResponse();
               parent = this.tsource.getParent();
           }
           catch (SourceException e) {
  
  
  
  1.5       +33 -14    cocoon-2.1/src/blocks/scratchpad/java/org/apache/cocoon/components/source/impl/UpdateTarget.java
  
  Index: UpdateTarget.java
  ===================================================================
  RCS file: /home/cvs/cocoon-2.1/src/blocks/scratchpad/java/org/apache/cocoon/components/source/impl/UpdateTarget.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- UpdateTarget.java	23 Mar 2004 16:28:54 -0000	1.4
  +++ UpdateTarget.java	24 Mar 2004 15:19:20 -0000	1.5
  @@ -27,6 +27,7 @@
   import org.apache.cocoon.components.cron.ConfigurableCronJob;
   import org.apache.excalibur.source.Source;
   import org.apache.excalibur.source.SourceResolver;
  +import org.apache.excalibur.source.SourceValidity;
   import org.apache.excalibur.source.impl.validity.ExpiresValidity;
   
   /**
  @@ -57,24 +58,23 @@
    * </ul>
    *  
    * @since 2.1.1
  - * @author <a href="mailto:cziegeler@apache.org">Carsten Ziegeler</a>
    * @version CVS $Id$
    */
   public class UpdateTarget extends AbstractLogEnabled
   implements Serviceable, ConfigurableCronJob {
       
       // service dependencies
  -    protected ServiceManager manager;
  -    protected SourceResolver resolver;
  +    private ServiceManager manager;
  +    private SourceResolver resolver;
       
       // configuration
  -    protected String uri;
  -    protected String cacheRole;
  -    protected int expires;
  -    protected boolean failSafe;
  +    private String uri;
  +    private String cacheRole;
  +    private int expires;
  +    private boolean failSafe;
       
       // the key under which to store the CachedResponse in the Cache
  -    protected SimpleCacheKey cacheKey;
  +    private SimpleCacheKey cacheKey;
       
           
       // ---------------------------------------------------- Lifecycle
  @@ -109,8 +109,8 @@
        */
       public void execute(String name) {
           if (this.uri != null) {
  -            if (this.getLogger().isInfoEnabled()) {
  -                this.getLogger().info("Refreshing " + this.uri);
  +            if (this.getLogger().isDebugEnabled()) {
  +                this.getLogger().debug("Refreshing " + this.uri);
               }
               
               Source source = null;
  @@ -120,7 +120,18 @@
                   cache = (Cache) this.manager.lookup(this.cacheRole);
                   source = this.resolver.resolveURI(this.uri);
                   
  +                // check if the source is really expired and invalid
                   CachedSourceResponse response = (CachedSourceResponse) cache.get(this.cacheKey);
  +                if (response != null) {
  +                    final SourceValidity sourceValidity = response.getValidityObjects()[1];
  +                    if (CachingSource.isValid(sourceValidity, source)) {
  +                        if (getLogger().isDebugEnabled()) {
  +                            getLogger().debug("Cached response is still valid " +
                                "for source " + this.uri + ".");
  +                        }
  +                        response.getValidityObjects()[0] = new ExpiresValidity(this.expires * 1000);
  +                        return;
  +                    }
  +                }
                   
                   if (source.exists()) {
                       
  @@ -133,7 +144,9 @@
                       }
                       
                       // create a new cached response
  -                    response = new CachedSourceResponse(new ExpiresValidity(this.expires * 1000));
  +                    final ExpiresValidity cacheValidity = new ExpiresValidity(this.expires * 1000);
  +                    final SourceValidity sourceValidity = source.getValidity();
  +                    response = new CachedSourceResponse(new SourceValidity[] {cacheValidity, sourceValidity});
                       
                       // only create objects that have previously been used
                       if (binary != null) {
  @@ -146,17 +159,23 @@
                       }
                       // meta info is always set
                       response.setExtra(CachingSource.readMeta(source));
  -                    
                       cache.store(this.cacheKey, response);
                   }
                   else if (response != null) {
  +                    // FIXME: There is a potential problem when the parent
  +                    // source has not yet been updated thus listing this
  +                    // source still as one of its children. We'll have to remove 
  +                    // the parent's cached response here too.
  +                    if (getLogger().isDebugEnabled()) {
  +                        getLogger().debug("Source " + this.uri + " no longer exists." +
                            " Throwing out cached response.");
  +                    }
                       cache.remove(this.cacheKey);
                   }
               } catch (Exception e) {
                   if (!failSafe) {
                       // the content expires, so remove it
                       cache.remove(cacheKey);
  -                    getLogger().warn("Exception during updating " + this.uri, e);
  +                    getLogger().warn("Exception during updating of source " + this.uri, e);
                   }
                   else {
                       getLogger().warn("Updating of source " + this.uri + " failed. " +