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. " +