This is an automated email from the ASF dual-hosted git repository. thiagohp pushed a commit to branch better-page-invalidation in repository https://gitbox.apache.org/repos/asf/tapestry-5.git
The following commit(s) were added to refs/heads/better-page-invalidation by this push: new 727770e59 TAP5-2742: component dependency and page classloader context preloading 727770e59 is described below commit 727770e59dc3f448fd00f21ed8c648270e849c5b Author: Thiago H. de Paula Figueiredo <thi...@arsmachina.com.br> AuthorDate: Sun Jun 11 19:47:38 2023 -0300 TAP5-2742: component dependency and page classloader context preloading --- .../tapestry5/corelib/pages/PageCatalog.java | 15 ++++++ .../services/pageload/PageClassLoaderContext.java | 2 +- .../pageload/PageClassLoaderContextManager.java | 7 +++ .../PageClassLoaderContextManagerImpl.java | 61 +++++++++++++++++++++- .../apache/tapestry5/corelib/pages/PageCatalog.tml | 3 ++ 5 files changed, 86 insertions(+), 2 deletions(-) diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/corelib/pages/PageCatalog.java b/tapestry-core/src/main/java/org/apache/tapestry5/corelib/pages/PageCatalog.java index 31c557649..a8472be8a 100644 --- a/tapestry-core/src/main/java/org/apache/tapestry5/corelib/pages/PageCatalog.java +++ b/tapestry-core/src/main/java/org/apache/tapestry5/corelib/pages/PageCatalog.java @@ -22,6 +22,7 @@ import java.util.List; import java.util.Set; import org.apache.tapestry5.MarkupWriter; +import org.apache.tapestry5.SymbolConstants; import org.apache.tapestry5.alerts.AlertManager; import org.apache.tapestry5.annotations.InjectComponent; import org.apache.tapestry5.annotations.Persist; @@ -61,6 +62,7 @@ import org.apache.tapestry5.services.ComponentClassResolver; import org.apache.tapestry5.services.ajax.AjaxResponseRenderer; import org.apache.tapestry5.services.javascript.JavaScriptSupport; import org.apache.tapestry5.services.pageload.ComponentResourceSelector; +import org.apache.tapestry5.services.pageload.PageClassLoaderContextManager; /** * Lists out the currently loaded pages, using a {@link org.apache.tapestry5.corelib.components.Grid}. @@ -78,6 +80,11 @@ public class PageCatalog @Inject @Symbol(TapestryHttpSymbolConstants.PRODUCTION_MODE) private boolean productionMode; + + @Property + @Inject + @Symbol(SymbolConstants.MULTIPLE_CLASSLOADERS) + private boolean multipleClassLoaders; @Inject private PageSource pageSource; @@ -151,6 +158,9 @@ public class PageCatalog @Inject private AjaxResponseRenderer ajaxResponseRenderer; + @Inject + private PageClassLoaderContextManager pageClassLoaderContextManager; + void pageLoaded() { model = beanModelSource.createDisplayModel(Page.class, messages); @@ -209,6 +219,11 @@ public class PageCatalog return pageSource.getAllPages(); } + void onActionFromPreloadPageClassLoaderContexts() + { + pageClassLoaderContextManager.preload(); + } + Object onClearPage(String className) { final String logicalName = resolver.getLogicalName(className); diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/services/pageload/PageClassLoaderContext.java b/tapestry-core/src/main/java/org/apache/tapestry5/services/pageload/PageClassLoaderContext.java index 7ebb41424..8ae71f5f4 100644 --- a/tapestry-core/src/main/java/org/apache/tapestry5/services/pageload/PageClassLoaderContext.java +++ b/tapestry-core/src/main/java/org/apache/tapestry5/services/pageload/PageClassLoaderContext.java @@ -208,7 +208,7 @@ public class PageClassLoaderContext /** * Removes a child context. */ - public void removeChildren(PageClassLoaderContext context) + public void removeChild(PageClassLoaderContext context) { children.remove(context); } diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/services/pageload/PageClassLoaderContextManager.java b/tapestry-core/src/main/java/org/apache/tapestry5/services/pageload/PageClassLoaderContextManager.java index c6e63676c..b37f0a0fc 100644 --- a/tapestry-core/src/main/java/org/apache/tapestry5/services/pageload/PageClassLoaderContextManager.java +++ b/tapestry-core/src/main/java/org/apache/tapestry5/services/pageload/PageClassLoaderContextManager.java @@ -88,5 +88,12 @@ public interface PageClassLoaderContextManager * Invalidates the "unknown" page classloader context context. */ void invalidateUnknownContext(); + + /** + * Preloads all data, first by collecting dependency data for all existing pages + * and the components, mixins and superclasses they use, then creating the + * page classloader contexts. + */ + void preload(); } diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/services/pageload/PageClassLoaderContextManagerImpl.java b/tapestry-core/src/main/java/org/apache/tapestry5/services/pageload/PageClassLoaderContextManagerImpl.java index bbfa1b7af..05df15c08 100644 --- a/tapestry-core/src/main/java/org/apache/tapestry5/services/pageload/PageClassLoaderContextManagerImpl.java +++ b/tapestry-core/src/main/java/org/apache/tapestry5/services/pageload/PageClassLoaderContextManagerImpl.java @@ -482,7 +482,7 @@ public class PageClassLoaderContextManagerImpl implements PageClassLoaderContext context.invalidate(); if (context.getParent() != null) { - context.getParent().removeChildren(context); + context.getParent().removeChild(context); } } return classNames; @@ -621,4 +621,63 @@ public class PageClassLoaderContextManagerImpl implements PageClassLoaderContext return clasz; } + @Override + public void preload() + { + + final PageClassLoaderContext context = new PageClassLoaderContext(PageClassLoaderContext.UNKOWN_CONTEXT_NAME, root, + Collections.emptySet(), + plasticProxyFactoryProvider.apply(root.getClassLoader()), + this::get); + + final List<String> pageNames = componentClassResolver.getPageNames(); + final List<String> classNames = new ArrayList<>(pageNames.size()); + + long start = System.currentTimeMillis(); + + LOGGER.info("Preloading dependency information for {} pages", pageNames.size()); + + for (String page : pageNames) + { + try + { + final String className = componentClassResolver.resolvePageNameToClassName(page); + componentDependencyRegistry.register(context.getClassLoader().loadClass(className)); + classNames.add(className); + } catch (ClassNotFoundException e) + { + throw new RuntimeException(e); + } + } + + long finish = System.currentTimeMillis(); + + if (LOGGER.isInfoEnabled()) + { + LOGGER.info(String.format("Dependency information gathered in %.3f ms", (finish - start) / 1000.0)); + } + + context.invalidate(); + + LOGGER.info("Starting preloading page classloader contexts"); + + start = System.currentTimeMillis(); + + for (int i = 0; i < 10; i++) + { + for (String className : classNames) + { + get(className); + } + } + + finish = System.currentTimeMillis(); + + if (LOGGER.isInfoEnabled()) + { + LOGGER.info(String.format("Preloading of page classloadercontexts finished in %.3f ms", (finish - start) / 1000.0)); + } + + } + } diff --git a/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/pages/PageCatalog.tml b/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/pages/PageCatalog.tml index 078ac9f7d..0e8242331 100644 --- a/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/pages/PageCatalog.tml +++ b/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/pages/PageCatalog.tml @@ -44,6 +44,9 @@ </t:if> <t:actionlink t:id="runGC" zone="pages" class="btn btn-default">Run the GC</t:actionlink> <t:actionlink t:id="storeDependencyInformation" zone="pages" class="btn btn-warning">Store dependency information</t:actionlink> + <t:if test="multipleClassLoaders"> + <t:actionlink t:id="preloadPageClassLoaderContexts" class="btn btn-default">Preload dependency information and page classloader contexts</t:actionlink> + </t:if> </div>