Return-Path: Delivered-To: apmail-cocoon-cvs-archive@www.apache.org Received: (qmail 44894 invoked from network); 2 Oct 2005 12:33:20 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur.apache.org with SMTP; 2 Oct 2005 12:33:20 -0000 Received: (qmail 53897 invoked by uid 500); 2 Oct 2005 12:33:17 -0000 Delivered-To: apmail-cocoon-cvs-archive@cocoon.apache.org Received: (qmail 53765 invoked by uid 500); 2 Oct 2005 12:33:16 -0000 Mailing-List: contact cvs-help@cocoon.apache.org; run by ezmlm Precedence: bulk Reply-To: dev@cocoon.apache.org list-help: list-unsubscribe: List-Post: List-Id: Delivered-To: mailing list cvs@cocoon.apache.org Received: (qmail 53754 invoked by uid 99); 2 Oct 2005 12:33:16 -0000 X-ASF-Spam-Status: No, hits=-9.8 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME X-Spam-Check-By: apache.org Received: from [209.237.227.194] (HELO minotaur.apache.org) (209.237.227.194) by apache.org (qpsmtpd/0.29) with SMTP; Sun, 02 Oct 2005 05:33:16 -0700 Received: (qmail 44769 invoked by uid 65534); 2 Oct 2005 12:32:54 -0000 Message-ID: <20051002123254.44757.qmail@minotaur.apache.org> Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r293102 - in /cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/components/flow: ContinuationsManagerImpl.java WebContinuation.java Date: Sun, 02 Oct 2005 12:32:50 -0000 To: cvs@cocoon.apache.org From: reinhard@apache.org X-Mailer: svnmailer-1.0.5 X-Virus-Checked: Checked by ClamAV on apache.org X-Spam-Rating: minotaur.apache.org 1.6.2 0/1000/N Author: reinhard Date: Sun Oct 2 05:32:38 2005 New Revision: 293102 URL: http://svn.apache.org/viewcvs?rev=293102&view=rev Log: make ContinuationsManagerImpl extensible so that it is possible to implement your own continuations invalidation strategy; code formatting Modified: cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/components/flow/ContinuationsManagerImpl.java cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/components/flow/WebContinuation.java Modified: cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/components/flow/ContinuationsManagerImpl.java URL: http://svn.apache.org/viewcvs/cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/components/flow/ContinuationsManagerImpl.java?rev=293102&r1=293101&r2=293102&view=diff ============================================================================== --- cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/components/flow/ContinuationsManagerImpl.java (original) +++ cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/components/flow/ContinuationsManagerImpl.java Sun Oct 2 05:32:38 2005 @@ -77,7 +77,7 @@ extends AbstractLogEnabled implements ContinuationsManager, Component, Configurable, ThreadSafe, Instrumentable, Serviceable, Contextualizable { - + static final int CONTINUATION_ID_LENGTH = 20; static final String EXPIRE_CONTINUATIONS = "expire-continuations"; @@ -113,20 +113,21 @@ */ protected SortedSet expirations = Collections.synchronizedSortedSet(new TreeSet()); - private String instrumentableName; - private ValueInstrument continuationsCount; - private int continuationsCounter; - private ValueInstrument forestSize; - private ValueInstrument expirationsSize; - private CounterInstrument continuationsCreated; - private CounterInstrument continuationsInvalidated; - private boolean isContinuationSharingBugCompatible; - private boolean bindContinuationsToSession; + protected String instrumentableName; + protected ValueInstrument continuationsCount; + protected int continuationsCounter; + protected ValueInstrument forestSize; + protected ValueInstrument expirationsSize; + protected CounterInstrument continuationsCreated; + protected CounterInstrument continuationsInvalidated; + protected boolean isContinuationSharingBugCompatible; + protected boolean bindContinuationsToSession; - private ServiceManager serviceManager; - private Context context; + protected ServiceManager serviceManager; + protected Context context; public ContinuationsManagerImpl() throws Exception { + try { random = SecureRandom.getInstance("SHA1PRNG"); } catch(java.security.NoSuchAlgorithmException nsae) { @@ -149,12 +150,17 @@ } public void configure(Configuration config) { + System.err.println("configure ContinuationsManagerImpl"); this.defaultTimeToLive = config.getAttributeAsInteger("time-to-live", (3600 * 1000)); this.isContinuationSharingBugCompatible = config.getAttributeAsBoolean("continuation-sharing-bug-compatible", false); this.bindContinuationsToSession = config.getAttributeAsBoolean( "session-bound-continuations", false ); - if (!this.bindContinuationsToSession) + + // create a global ContinuationsHolder if this the "session-bound-continuations" parameter is set to false + if(!this.bindContinuationsToSession) { this.continuationsHolder = new WebContinuationsHolder(); + } + // create a thread that invalidates the continuations final Configuration expireConf = config.getChild("expirations-check"); final long initialDelay = expireConf.getChild("offset", true).getValueAsLong(180000); final long interval = expireConf.getChild("period", true).getValueAsLong(180000); @@ -208,18 +214,10 @@ forest.add(wk); forestSize.setValue(forest.size()); } else { - // REVISIT: This places only the "leaf" nodes in the expirations Sorted Set. - // do we really want to do this? - if (parent.getChildren().size() < 2) { - expirations.remove(parent); - } + handleParentContinuationExpiration(parent); } - expirations.add(wk); - expirationsSize.setValue(expirations.size()); - - // No need to add the WebContinuation in idToWebCont as it was - // already done during its construction. + handleLeafContinuationExpiration(wk); if (getLogger().isDebugEnabled()) { getLogger().debug("WK: Created continuation " + wk.getId()); @@ -228,15 +226,37 @@ return wk; } + /** + * When a new continuation is created in @link #createWebContinuation(Object, WebContinuation, int, String, ContinuationsDisposer), + * it is registered in the expiration set in order to be evaluated by the invalidation mechanism. + */ + protected void handleLeafContinuationExpiration(WebContinuation wk) { + expirations.add(wk); + expirationsSize.setValue(expirations.size()); + } + + /** + * When a new continuation is created in @link #createWebContinuation(Object, WebContinuation, int, String, ContinuationsDisposer), + * its parent continuation is removed from the expiration set. This way only leaf continuations are part of + * the expiration set. + */ + protected void handleParentContinuationExpiration(WebContinuation parent) { + if (parent.getChildren().size() < 2) { + expirations.remove(parent); + } + } + + public WebContinuation lookupWebContinuation(String id, String interpreterId) { // REVISIT: Is the following check needed to avoid threading issues: // return wk only if !(wk.hasExpired) ? WebContinuationsHolder continuationsHolder = lookupWebContinuationsHolder(false); - if (continuationsHolder == null) + if (continuationsHolder == null) { return null; + } WebContinuation kont = continuationsHolder.get(id); - if ( kont != null ) { + if(kont != null) { boolean interpreterMatches = kont.interpreterMatches(interpreterId); if (!interpreterMatches && getLogger().isWarnEnabled()) { getLogger().warn("WK: Continuation (" + kont.getId() @@ -254,9 +274,6 @@ * for it. The identifier is generated using a cryptographically strong * algorithm to prevent people to generate their own identifiers. * - *

It has the side effect of interning the continuation object in - * the idToWebCont hash table. - * * @param kont an Object value representing continuation * @param parent value representing parent WebContinuation * @param ttl WebContinuation time to live @@ -265,7 +282,7 @@ * cleanup of the continuation. * @return the generated WebContinuation with unique identifier */ - private WebContinuation generateContinuation(Object kont, + protected WebContinuation generateContinuation(Object kont, WebContinuation parent, int ttl, String interpreterId, @@ -286,13 +303,15 @@ final String id = new String(result); synchronized (continuationsHolder) { if (!continuationsHolder.contains(id)) { - if (this.bindContinuationsToSession) + if (this.bindContinuationsToSession) { wk = new HolderAwareWebContinuation(id, kont, parent, ttl, interpreterId, disposer, continuationsHolder); - else + } + else { wk = new WebContinuation(id, kont, parent, ttl, interpreterId, disposer); + } continuationsHolder.addContinuation(wk); synchronized (continuationsCount) { continuationsCounter++; @@ -317,7 +336,7 @@ _invalidate(continuationsHolder, wk); } - private void _invalidate(WebContinuationsHolder continuationsHolder, WebContinuation wk) { + protected void _invalidate(WebContinuationsHolder continuationsHolder, WebContinuation wk) { if (getLogger().isDebugEnabled()) { getLogger().debug("WK: Manual expire of continuation " + wk.getId()); } @@ -356,7 +375,7 @@ * * @param wk the continuation to dispose. */ - private void disposeContinuation(WebContinuationsHolder continuationsHolder, WebContinuation wk) { + protected void disposeContinuation(WebContinuationsHolder continuationsHolder, WebContinuation wk) { continuationsHolder.removeContinuation(wk); synchronized( continuationsCount ) { continuationsCounter--; @@ -374,8 +393,7 @@ * * @param wk WebContinuation node */ - private void removeContinuation(WebContinuationsHolder continuationsHolder, - WebContinuation wk) { + protected void removeContinuation(WebContinuationsHolder continuationsHolder, WebContinuation wk) { if (wk.getChildren().size() != 0) { return; } @@ -400,7 +418,7 @@ * Dump to Log file the current contents of * the expirations SortedSet */ - private void displayExpireSet() { + protected void displayExpireSet() { StringBuffer wkSet = new StringBuffer("\nWK; Expire set size: " + expirations.size()); Iterator i = expirations.iterator(); while (i.hasNext()) { @@ -440,24 +458,26 @@ if (getLogger().isDebugEnabled()) { now = System.currentTimeMillis(); - /* Continuations before clean up: + /* Continuations before clean up: */ getLogger().debug("WK: Forest before cleanup: " + forest.size()); displayAllContinuations(); displayExpireSet(); - */ + } // Clean up expired continuations int count = 0; WebContinuation wk; Iterator i = expirations.iterator(); - while (i.hasNext() && ((wk = (WebContinuation) i.next()).hasExpired())) { + while(i.hasNext() && ((wk = (WebContinuation) i.next()).hasExpired())) { i.remove(); WebContinuationsHolder continuationsHolder = null; - if ( wk instanceof HolderAwareWebContinuation ) + if(wk instanceof HolderAwareWebContinuation) { continuationsHolder = ((HolderAwareWebContinuation) wk).getContinuationsHolder(); - else + } + else { continuationsHolder = this.continuationsHolder; + } removeContinuation(continuationsHolder, wk); count++; } @@ -465,13 +485,13 @@ if (getLogger().isDebugEnabled()) { getLogger().debug("WK Cleaned up " + count + " continuations in " + - (System.currentTimeMillis() - now)); + (System.currentTimeMillis() - now) + " ms"); + + /* Continuations after clean up: */ +// getLogger().debug("WK: Forest after cleanup: " + forest.size()); +// displayAllContinuations(); +// displayExpireSet(); - /* Continuations after clean up: - getLogger().debug("WK: Forest after cleanup: " + forest.size()); - displayAllContinuations(); - displayExpireSet(); - */ } } @@ -480,7 +500,7 @@ * about session invalidation. Invalidates all continuations held by passed * continuationsHolder. */ - private void invalidateContinuations( + protected void invalidateContinuations( WebContinuationsHolder continuationsHolder) { // TODO: this avoids ConcurrentModificationException, still this is not // the best solution and should be changed @@ -534,9 +554,8 @@ * A holder for WebContinuations. When bound to session notifies the * continuations manager of session invalidation. */ - private class WebContinuationsHolder implements HttpSessionBindingListener { - private final static String CONTINUATIONS_HOLDER = - "o.a.c.c.f.SCMI.WebContinuationsHolder"; + protected class WebContinuationsHolder implements HttpSessionBindingListener { + private final static String CONTINUATIONS_HOLDER = "o.a.c.c.f.SCMI.WebContinuationsHolder"; private Map holder = Collections.synchronizedMap(new HashMap()); @@ -577,7 +596,7 @@ * holder. This information is needed to cleanup a proper holder after * continuation's expiration time. */ - private static class HolderAwareWebContinuation extends WebContinuation { + protected static class HolderAwareWebContinuation extends WebContinuation { private WebContinuationsHolder continuationsHolder; public HolderAwareWebContinuation(String id, Object continuation, @@ -613,4 +632,5 @@ } return beanList; } + } Modified: cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/components/flow/WebContinuation.java URL: http://svn.apache.org/viewcvs/cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/components/flow/WebContinuation.java?rev=293102&r1=293101&r2=293102&view=diff ============================================================================== --- cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/components/flow/WebContinuation.java (original) +++ cocoon/branches/BRANCH_2_1_X/src/java/org/apache/cocoon/components/flow/WebContinuation.java Sun Oct 2 05:32:38 2005 @@ -420,7 +420,7 @@ public boolean hasExpired() { long currentTime = System.currentTimeMillis(); long expireTime = this.getLastAccessTime() + this.timeToLive; - + return (currentTime > expireTime); }