You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by hl...@apache.org on 2011/07/13 02:03:08 UTC

svn commit: r1145828 - in /tapestry/tapestry5/trunk/tapestry-core/src: main/java/org/apache/tapestry5/ main/java/org/apache/tapestry5/internal/services/ main/java/org/apache/tapestry5/internal/structure/ main/java/org/apache/tapestry5/services/ test/ja...

Author: hlship
Date: Wed Jul 13 00:03:08 2011
New Revision: 1145828

URL: http://svn.apache.org/viewvc?rev=1145828&view=rev
Log:
TAP5-1572: Define symbols for controlling page source pruning and add code to PageSourceImpl to periodically check for prunable pages

Modified:
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/SymbolConstants.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PageSourceImpl.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/Page.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/PageImpl.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/services/AppModule.java

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/SymbolConstants.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/SymbolConstants.java?rev=1145828&r1=1145827&r2=1145828&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/SymbolConstants.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/SymbolConstants.java Wed Jul 13 00:03:08 2011
@@ -21,7 +21,7 @@ import org.apache.tapestry5.services.jav
 
 /**
  * Defines the names of symbols used to configure Tapestry.
- * 
+ *
  * @see org.apache.tapestry5.ioc.services.SymbolSource
  */
 public class SymbolConstants
@@ -36,7 +36,7 @@ public class SymbolConstants
      * A version of {@link #PRODUCTION_MODE} as a symbol reference. This can be used as the default value
      * of other symbols, to indicate that their default matches whatever PRODUCTION_MODE is set to, which is quite
      * common.
-     * 
+     *
      * @since 5.2.0
      */
     public static final String PRODUCTION_MODE_VALUE = String.format("${%s}", PRODUCTION_MODE);
@@ -45,7 +45,7 @@ public class SymbolConstants
      * If set to "true", then action requests will render a page markup response immediately, rather than sending a
      * redirect to render the response. "Action request" is an outdated term for "component event request" (i.e., most
      * links and all form submissions).
-     * 
+     *
      * @deprecated In 5.3, to be removed (along with the support it implies) in 5.4
      */
     public static final String SUPPRESS_REDIRECT_FROM_ACTION_REQUESTS = "tapestry.suppress-redirect-from-action-requests";
@@ -111,7 +111,7 @@ public class SymbolConstants
     /**
      * Identifies the default persistence strategy for all pages that do not provide an override (using this value as
      * {@link org.apache.tapestry5.annotations.Meta key}).
-     * 
+     *
      * @since 5.1.0.0
      */
     public static final String PERSISTENCE_STRATEGY = "tapestry.persistence-strategy";
@@ -119,7 +119,7 @@ public class SymbolConstants
     /**
      * Minimum output stream size, in bytes, before output is compressed using GZIP. Shorter streams are not compressed.
      * Tapestry buffers this amount and switches to a GZIP output stream as needed. The default is "100".
-     * 
+     *
      * @see #GZIP_COMPRESSION_ENABLED
      * @since 5.1.0.0
      */
@@ -131,17 +131,17 @@ public class SymbolConstants
      * value is semi-random and different for each execution, which will adversely affect client caching, but is
      * reasonable
      * for development.
-     * 
-     * @since 5.1.0.0
+     *
      * @see AssetDispatcher
      * @see AssetPathConstructor
+     * @since 5.1.0.0
      */
     public static final String APPLICATION_VERSION = "tapestry.application-version";
 
     /**
      * Used to omit the normal Tapestry framework generator meta tag. The meta tag is rendered by default, but clients
      * who do not wish to advertise their use of Tapestry may set this symbol to "true".
-     * 
+     *
      * @since 5.1.0.0
      */
     public static final String OMIT_GENERATOR_META = "tapestry.omit-generator-meta";
@@ -150,7 +150,7 @@ public class SymbolConstants
      * If "true" (the default) then GZip compression is enabled for dynamic requests and for static assets. If you are
      * using a server that handles GZip compression for you, or you don't want to ue the extra processing power
      * necessary to GZIP requests, then override this to "false".
-     * 
+     *
      * @see #MIN_GZIP_SIZE
      * @since 5.1.0.0
      */
@@ -160,7 +160,7 @@ public class SymbolConstants
      * If "true" (which itself defaults to production mode), then the {@link org.apache.tapestry5.annotations.Secure}
      * annotation will be honored. If "false" (i.e., development mode), then the annotation and related HTTP/HTTPS
      * logic is ignored.
-     * 
+     *
      * @since 5.1.0.1
      */
     public static final String SECURE_ENABLED = "tapestry.secure-enabled";
@@ -172,7 +172,7 @@ public class SymbolConstants
      * {@link org.apache.tapestry5.services.LinkCreationListener2} (registered with the
      * {@link org.apache.tapestry5.services.LinkCreationHub}) in order to add the locale as a query parameter (or
      * provide some alternate means of persisting the locale between requests).
-     * 
+     *
      * @since 5.1.0.1
      */
     public static final String ENCODE_LOCALE_INTO_PATH = "tapestry.encode-locale-into-path";
@@ -180,14 +180,14 @@ public class SymbolConstants
     /**
      * If "true" then JavaScript files in a {@link JavaScriptStack} will be combined into a single virtual JavaScript
      * file. Defaults to "true" in production mode.
-     * 
+     *
      * @since 5.1.0.2
      */
     public static final String COMBINE_SCRIPTS = "tapestry.combine-scripts";
 
     /**
      * If "true" then Blackbird JavaScript console is enabled.
-     * 
+     *
      * @since 5.2.0
      * @deprecated in 5.3, with no replacement (due to removal of Blackbird console entirely)
      */
@@ -196,42 +196,42 @@ public class SymbolConstants
     /**
      * The default time interval that cookies created by Tapestry will be kept in the client web browser. The default is
      * "7 d" (that is, seven days).
-     * 
+     *
      * @since 5.2.0
      */
     public static final String COOKIE_MAX_AGE = "tapestry.default-cookie-max-age";
 
     /**
      * The logical name of the start page, the page that is rendered for the root URL.
-     * 
+     *
      * @since 5.2.0
      */
     public static final String START_PAGE_NAME = "tapestry.start-page-name";
 
     /**
      * The default stylesheet automatically injected into every rendered HTML page.
-     * 
+     *
      * @since 5.2.0
      */
     public static final String DEFAULT_STYLESHEET = "tapestry.default-stylesheet";
 
     /**
      * The Asset path to the embedded copy of script.aculo.us packaged with Tapestry.
-     * 
+     *
      * @since 5.2.0
      */
     public static final String SCRIPTACULOUS = "tapestry.scriptaculous";
 
     /**
      * The Asset path to the embedded datepicker.
-     * 
+     *
      * @since 5.2.0
      */
     public static final String DATEPICKER = "tapestry.datepicker";
 
     /**
      * The Asset path to the embedded copy of blackbird packaged with Tapestry.
-     * 
+     *
      * @since 5.2.0
      * @deprecated in 5.3 with no replacement
      */
@@ -240,7 +240,7 @@ public class SymbolConstants
     /**
      * If "true", then JSON page initialization content is compressed; if "false"
      * then extra white space is added (pretty printing). Defaults to "true" in production mode.
-     * 
+     *
      * @since 5.2.0
      */
     public static final String COMPACT_JSON = "tapestry.compact-json";
@@ -251,7 +251,7 @@ public class SymbolConstants
      * allowing more visibility into which components rendered which markup. Defaults to "false". Component render
      * tracing may be
      * enabled per-request by the presence of a request parameter "t:component-trace" with a value of "true".
-     * 
+     *
      * @since 5.2.5
      */
     public static final String COMPONENT_RENDER_TRACING_ENABLED = "tapestry.component-render-tracing-enabled";
@@ -262,7 +262,7 @@ public class SymbolConstants
      * in which case system will use request.getServerName(). Not the same as environment variable HOSTNAME, but you can
      * also
      * contribute "$HOSTNAME" as the value to make it the same as the environment variable HOSTNAME.
-     * 
+     *
      * @since 5.3
      */
     public static final String HOSTNAME = "tapestry.hostname";
@@ -271,7 +271,7 @@ public class SymbolConstants
      * The hostport that application should use when constructing an absolute URL. The default is "0", i.e. use the port
      * value from
      * the request.
-     * 
+     *
      * @since 5.3
      */
     public static final String HOSTPORT = "tapestry.hostport";
@@ -280,7 +280,7 @@ public class SymbolConstants
      * The secure (https) hostport that application should use when constructing an absolute URL. The default is "0",
      * i.e. use
      * the value from the request.
-     * 
+     *
      * @since 5.3
      */
     public static final String HOSTPORT_SECURE = "tapestry.hostport-secure";
@@ -289,10 +289,10 @@ public class SymbolConstants
      * If "true", then resources (individually or when aggregated into stacks) will be minimized via the
      * {@link ResourceMinimizer} service. If "false", then minification is disabled. Tracks production mode
      * (minification is normally disabled in development mode).
-     * <p>
+     * <p/>
      * Note that Tapestry's default implementation of {@link ResourceMinimizer} does nothing; minification is provided
      * by add-on libraries.
-     * 
+     *
      * @since 5.3
      */
     public static final String MINIFICATION_ENABLED = "tapestry.enable-minification";
@@ -301,11 +301,27 @@ public class SymbolConstants
      * If "true" then at the end of each request the
      * {@link org.apache.tapestry5.services.SessionPersistedObjectAnalyzer} will be called on each session persisted
      * object that was accessed during the request.
-     * <p>
+     * <p/>
      * This is provided as a performance enhancement for servers that do not use clustered sessions.
      *
      * @since 5.3
      */
     public static final String CLUSTERED_SESSIONS = "tapestry.clustered-sessions";
 
+    /**
+     * The interval (in milliseconds) at which the {@link org.apache.tapestry5.internal.services.PageSource} checks for
+     * inactive pages that can be discarded. The default is "5 m" (every five minutes).
+     *
+     * @since 5.3
+     */
+    public static final String PAGE_SOURCE_CHECK_INTERVAL = "tapestry.page-source-check-interval";
+
+    /**
+     * The maximum amount of time, in milliseconds, that an instantiated page instance may be kept in memory
+     * before being discarded. The frequency of checks for such pages is determined by {@link #PAGE_SOURCE_CHECK_INTERVAL}.
+     * The default is "15 m" (fifteen minutes).
+     *
+     * @since 5.3
+     */
+    public static final String PAGE_SOURCE_ACTIVE_WINDOW = "tapestry.page-cache-active-window";
 }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PageSourceImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PageSourceImpl.java?rev=1145828&r1=1145827&r2=1145828&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PageSourceImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/PageSourceImpl.java Wed Jul 13 00:03:08 2011
@@ -14,13 +14,23 @@
 
 package org.apache.tapestry5.internal.services;
 
-import java.util.Map;
-
+import org.apache.tapestry5.SymbolConstants;
 import org.apache.tapestry5.internal.structure.Page;
+import org.apache.tapestry5.ioc.annotations.IntermediateType;
+import org.apache.tapestry5.ioc.annotations.PostInjection;
+import org.apache.tapestry5.ioc.annotations.Symbol;
 import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry5.ioc.services.cron.IntervalSchedule;
+import org.apache.tapestry5.ioc.services.cron.PeriodicExecutor;
+import org.apache.tapestry5.ioc.util.TimeInterval;
 import org.apache.tapestry5.services.InvalidationListener;
 import org.apache.tapestry5.services.pageload.ComponentRequestSelectorAnalyzer;
 import org.apache.tapestry5.services.pageload.ComponentResourceSelector;
+import org.slf4j.Logger;
+
+import java.util.Date;
+import java.util.Iterator;
+import java.util.Map;
 
 public class PageSourceImpl implements PageSource, InvalidationListener
 {
@@ -28,6 +38,10 @@ public class PageSourceImpl implements P
 
     private final PageLoader pageLoader;
 
+    private final long activeWindow;
+
+    private final Logger logger;
+
     private static final class CachedPageKey
     {
         final String pageName;
@@ -61,10 +75,57 @@ public class PageSourceImpl implements P
 
     private final Map<CachedPageKey, Page> pageCache = CollectionFactory.newConcurrentMap();
 
-    public PageSourceImpl(PageLoader pageLoader, ComponentRequestSelectorAnalyzer selectorAnalyzer)
+    public PageSourceImpl(PageLoader pageLoader, ComponentRequestSelectorAnalyzer selectorAnalyzer,
+
+                          @Symbol(SymbolConstants.PAGE_SOURCE_ACTIVE_WINDOW)
+                          @IntermediateType(TimeInterval.class)
+                          long activeWindow, Logger logger)
     {
         this.pageLoader = pageLoader;
         this.selectorAnalyzer = selectorAnalyzer;
+        this.activeWindow = activeWindow;
+        this.logger = logger;
+    }
+
+    @PostInjection
+    public void startJanitor(PeriodicExecutor executor, @Symbol(SymbolConstants.PAGE_SOURCE_CHECK_INTERVAL)
+    @IntermediateType(TimeInterval.class)
+    long checkInterval)
+    {
+        executor.addJob(new IntervalSchedule(checkInterval), "PagePool cleanup", new Runnable()
+        {
+            public void run()
+            {
+                prune();
+            }
+        });
+    }
+
+    private void prune()
+    {
+        Iterator<Page> iterator = pageCache.values().iterator();
+
+        int count = 0;
+
+        long cutoff = System.currentTimeMillis() - activeWindow;
+
+        while (iterator.hasNext())
+        {
+            Page page = iterator.next();
+
+            if (page.getLastAttachTime() <= cutoff)
+            {
+                count++;
+                iterator.remove();
+            }
+        }
+
+        if (count > 0)
+        {
+            logger.info(String.format("Pruned %d page %s that had not been accessed since %s.", count,
+                    count == 1 ? "instance" : "instances",
+                    new Date(cutoff)));
+        }
     }
 
     public synchronized void objectWasInvalidated()

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/Page.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/Page.java?rev=1145828&r1=1145827&r2=1145828&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/Page.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/Page.java Wed Jul 13 00:03:08 2011
@@ -21,8 +21,6 @@ import org.apache.tapestry5.runtime.Page
 import org.apache.tapestry5.services.pageload.ComponentResourceSelector;
 import org.slf4j.Logger;
 
-import java.util.Locale;
-
 /**
  * Represents a unique page within the application. Pages are part of the <em>internal</em> structure of a Tapestry
  * application; end developers who refer to "page" are really referring to the {@link #getRootComponent() root
@@ -81,11 +79,11 @@ public interface Page
      * containingPageDidDetach().
      * <p/>
      * The page pool should discard pages that are dirty, rather than store them into the pool.
-     * <p>
+     * <p/>
      * Under Tapestry 5.2 and pool-less pages, the result is ignored; all mutable state is expected to be discarded
      * automatically from the {@link PerthreadManager}. A future release of Tapestry will likely convert this method to
      * type void.
-     * 
+     *
      * @return true if the page is "dirty", false otherwise
      * @see org.apache.tapestry5.runtime.PageLifecycleListener#containingPageDidDetach()
      */
@@ -95,7 +93,7 @@ public interface Page
      * Invoked to inform the page that it is attached to the current request. This occurs when a
      * page is first referenced within a request. If the page was created from scratch for this request, the call
      * to {@link #loaded()} will preceded the call to {@link #attached()}.
-     * <p>
+     * <p/>
      * First all listeners have {@link PageLifecycleListener#restoreStateBeforePageAttach()} invoked, followed by
      * {@link PageLifecycleListener#containingPageDidAttach()}.
      */
@@ -103,7 +101,7 @@ public interface Page
 
     /**
      * Inform the page that it is now completely loaded.
-     * 
+     *
      * @see org.apache.tapestry5.runtime.PageLifecycleListener#containingPageDidLoad()
      */
     void loaded();
@@ -115,7 +113,7 @@ public interface Page
 
     /**
      * Removes a listener that was previously added.
-     * 
+     *
      * @since 5.2.0
      */
     void removeLifecycleListener(PageLifecycleListener listener);
@@ -133,32 +131,26 @@ public interface Page
      * names in the nested id are matched without regards to case. A nested id of '' (the empty
      * string) returns the root
      * element of the page.
-     * 
-     * @throws IllegalArgumentException
-     *             if the nestedId does not correspond to a component
+     *
+     * @throws IllegalArgumentException if the nestedId does not correspond to a component
      */
     ComponentPageElement getComponentElementByNestedId(String nestedId);
 
     /**
      * Posts a change to a persistent field.
-     * 
-     * @param resources
-     *            the component resources for the component or mixin containing the field whose
-     *            value changed
-     * @param fieldName
-     *            the name of the field
-     * @param newValue
-     *            the new value for the field
+     *
+     * @param resources the component resources for the component or mixin containing the field whose
+     *                  value changed
+     * @param fieldName the name of the field
+     * @param newValue  the new value for the field
      */
     void persistFieldChange(ComponentResources resources, String fieldName, Object newValue);
 
     /**
      * Gets a change for a field within the component.
-     * 
-     * @param nestedId
-     *            the nested component id of the component containing the field
-     * @param fieldName
-     *            the name of the persistent field
+     *
+     * @param nestedId  the nested component id of the component containing the field
+     * @param fieldName the name of the persistent field
      * @return the value, or null if no value is stored
      */
     Object getFieldChange(String nestedId, String fieldName);
@@ -173,16 +165,15 @@ public interface Page
 
     /**
      * Adds a new listener for page reset events.
-     * 
-     * @param listener
-     *            will receive notifications when the page is accessed from a different page
+     *
+     * @param listener will receive notifications when the page is accessed from a different page
      * @since 5.2.0
      */
     void addResetListener(PageResetListener listener);
 
     /**
      * Returns true if there are any {@link PageResetListener} listeners.
-     * 
+     *
      * @since 5.2.0
      */
     boolean hasResetListeners();
@@ -191,4 +182,13 @@ public interface Page
      * Invoked to notify {@link PageResetListener} listeners.
      */
     void pageReset();
+
+    /**
+     * Returns time, in milliseconds, that the page was last attached. This is used by the {@link PagePool} to
+     * cull unused pages from memory.
+     *
+     * @return milliseconds time of last {@link #attached()}} call
+     * @since 5.3
+     */
+    long getLastAttachTime();
 }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/PageImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/PageImpl.java?rev=1145828&r1=1145827&r2=1145828&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/PageImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/structure/PageImpl.java Wed Jul 13 00:03:08 2011
@@ -14,10 +14,6 @@
 
 package org.apache.tapestry5.internal.structure;
 
-import java.util.List;
-import java.util.Map;
-import java.util.regex.Pattern;
-
 import org.apache.tapestry5.ComponentResources;
 import org.apache.tapestry5.internal.services.PersistentFieldManager;
 import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
@@ -30,6 +26,10 @@ import org.apache.tapestry5.services.Per
 import org.apache.tapestry5.services.pageload.ComponentResourceSelector;
 import org.slf4j.Logger;
 
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Pattern;
+
 public class PageImpl implements Page
 {
     private final String name;
@@ -50,6 +50,8 @@ public class PageImpl implements Page
 
     private final Map<String, ComponentPageElement> idToComponent = CollectionFactory.newCaseInsensitiveMap();
 
+    private volatile long lastAttach = System.currentTimeMillis();
+
     /**
      * Obtained from the {@link org.apache.tapestry5.internal.services.PersistentFieldManager} when
      * first needed,
@@ -60,17 +62,13 @@ public class PageImpl implements Page
     private static final Pattern SPLIT_ON_DOT = Pattern.compile("\\.");
 
     /**
-     * @param name
-     *            canonicalized page name
-     * @param selector
-     *            used to locate resources
-     * @param persistentFieldManager
-     *            for access to cross-request persistent values
-     * @param perThreadManager
-     *            for managing per-request mutable state
+     * @param name                   canonicalized page name
+     * @param selector               used to locate resources
+     * @param persistentFieldManager for access to cross-request persistent values
+     * @param perThreadManager       for managing per-request mutable state
      */
     public PageImpl(String name, ComponentResourceSelector selector, PersistentFieldManager persistentFieldManager,
-            PerthreadManager perThreadManager)
+                    PerthreadManager perThreadManager)
     {
         this.name = name;
         this.selector = selector;
@@ -154,8 +152,7 @@ public class PageImpl implements Page
             try
             {
                 listener.containingPageDidDetach();
-            }
-            catch (RuntimeException ex)
+            } catch (RuntimeException ex)
             {
                 getLogger().error(StructureMessages.detachFailure(listener, ex), ex);
                 result = true;
@@ -179,6 +176,8 @@ public class PageImpl implements Page
 
     public void attached()
     {
+        lastAttach = System.currentTimeMillis();
+
         for (PageLifecycleListener listener : lifecycleListeners)
             listener.restoreStateBeforePageAttach();
 
@@ -233,6 +232,11 @@ public class PageImpl implements Page
         }
     }
 
+    public long getLastAttachTime()
+    {
+        return lastAttach;
+    }
+
     public boolean hasResetListeners()
     {
         return !resetListeners.isEmpty();

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java?rev=1145828&r1=1145827&r2=1145828&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java Wed Jul 13 00:03:08 2011
@@ -1264,10 +1264,9 @@ public final class TapestryModule
      * href="https://issues.apache.org/jira/browse/TAP5-79">TAP5-79</a> for details. There are no longer any built-in
      * contributions to the configuration.
      *
-     * @param configuration
-     *         contributions of special factories for some constants, each
-     *         contributed factory may return a
-     *         binding if applicable, or null otherwise
+     * @param configuration contributions of special factories for some constants, each
+     *                      contributed factory may return a
+     *                      binding if applicable, or null otherwise
      */
     public BindingFactory buildPropBindingFactory(List<BindingFactory> configuration, @Autobuild
     PropBindingFactory service)
@@ -2269,8 +2268,7 @@ public final class TapestryModule
      * <p/>
      * This contributes "class", "properties" and "tml" (the template extension).
      *
-     * @param configuration
-     *         collection of extensions
+     * @param configuration collection of extensions
      */
     public static void contributeResourceDigestGenerator(Configuration<String> configuration)
     {
@@ -2394,6 +2392,9 @@ public final class TapestryModule
         configuration.add(SymbolConstants.HOSTNAME, "");
         configuration.add(SymbolConstants.HOSTPORT, 0);
         configuration.add(SymbolConstants.HOSTPORT_SECURE, 0);
+
+        configuration.add(SymbolConstants.PAGE_SOURCE_CHECK_INTERVAL, "5 m");
+        configuration.add(SymbolConstants.PAGE_SOURCE_ACTIVE_WINDOW, "15 m");
     }
 
     /**
@@ -2707,8 +2708,7 @@ public final class TapestryModule
      * even if a user overrides the default
      * service implementation.
      *
-     * @param defaultSource
-     *         The serivce to decorate
+     * @param defaultSource The serivce to decorate
      * @param environment
      * @return
      */

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/services/AppModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/services/AppModule.java?rev=1145828&r1=1145827&r2=1145828&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/services/AppModule.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/services/AppModule.java Wed Jul 13 00:03:08 2011
@@ -14,44 +14,32 @@
 
 package org.apache.tapestry5.integration.app1.services;
 
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import java.io.IOException;
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-import java.net.URL;
-import java.util.List;
-import java.util.Map;
-
 import org.apache.tapestry5.SymbolConstants;
 import org.apache.tapestry5.ValueEncoder;
-import org.apache.tapestry5.integration.app1.data.DateHolder;
 import org.apache.tapestry5.integration.app1.data.ToDoItem;
 import org.apache.tapestry5.integration.app1.data.Track;
 import org.apache.tapestry5.internal.services.GenericValueEncoderFactory;
-import org.apache.tapestry5.ioc.Configuration;
-import org.apache.tapestry5.ioc.MappedConfiguration;
-import org.apache.tapestry5.ioc.OrderedConfiguration;
-import org.apache.tapestry5.ioc.Resource;
-import org.apache.tapestry5.ioc.ServiceBinder;
+import org.apache.tapestry5.ioc.*;
 import org.apache.tapestry5.ioc.annotations.Contribute;
 import org.apache.tapestry5.ioc.annotations.Marker;
 import org.apache.tapestry5.ioc.annotations.Value;
 import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
 import org.apache.tapestry5.ioc.services.ServiceOverride;
-import org.apache.tapestry5.services.BaseURLSource;
-import org.apache.tapestry5.services.ComponentClassTransformWorker;
-import org.apache.tapestry5.services.Request;
-import org.apache.tapestry5.services.RequestFilter;
-import org.apache.tapestry5.services.RequestHandler;
-import org.apache.tapestry5.services.ResourceDigestGenerator;
-import org.apache.tapestry5.services.Response;
-import org.apache.tapestry5.services.ValueEncoderFactory;
+import org.apache.tapestry5.services.*;
 import org.slf4j.Logger;
 
+import java.io.IOException;
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+import java.net.URL;
+import java.util.List;
+import java.util.Map;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
 /**
  * I was just dying to see how fast requests are!
  */
@@ -63,7 +51,7 @@ public class AppModule
      * interface.
      */
     @Target(
-    { PARAMETER, FIELD })
+            {PARAMETER, FIELD})
     @Retention(RUNTIME)
     @Documented
     public @interface Local
@@ -115,8 +103,7 @@ public class AppModule
                 try
                 {
                     return handler.service(request, response);
-                }
-                finally
+                } finally
                 {
                     long elapsed = System.nanoTime() - startTime;
 
@@ -128,8 +115,8 @@ public class AppModule
 
     public void contributeRequestHandler(OrderedConfiguration<RequestFilter> configuration,
 
-    @Local
-    RequestFilter filter)
+                                         @Local
+                                         RequestFilter filter)
     {
         configuration.add("Timing", filter);
     }
@@ -156,7 +143,8 @@ public class AppModule
 
         configuration.add("app.injected-symbol", "Symbol contributed to ApplicationDefaults");
 
-        configuration.add(SymbolConstants.BLACKBIRD_ENABLED, "true");
+        configuration.add(SymbolConstants.PAGE_SOURCE_ACTIVE_WINDOW, "30s");
+        configuration.add(SymbolConstants.PAGE_SOURCE_CHECK_INTERVAL, "15s");
     }
 
     public static void contributeIgnoredPathsFilter(Configuration<String> configuration)
@@ -242,7 +230,7 @@ public class AppModule
     }
 
     public static void contributeValueEncoderSource(MappedConfiguration<Class, ValueEncoderFactory> configuration,
-            final MusicLibrary library, final ToDoDatabase todoDatabase)
+                                                    final MusicLibrary library, final ToDoDatabase todoDatabase)
     {
         ValueEncoder<Track> trackEncoder = new ValueEncoder<Track>()
         {
@@ -286,7 +274,7 @@ public class AppModule
     }
 
     public static void contributeComponentMessagesSource(@Value("context:WEB-INF/pre-app.properties")
-    Resource preappResource, OrderedConfiguration<Resource> configuration)
+                                                         Resource preappResource, OrderedConfiguration<Resource> configuration)
     {
         configuration.add("PreApp", preappResource, "before:AppCatalog");
     }