Thank you Ben. I may have to go this route if I can’t find a way to make the page much lighter to load.
Geoff > On 28 Dec 2022, at 5:55 pm, Ben Weidig <b...@netzgut.net> wrote: > > Hi Geoff, > > I've read through the SoftReference documentation and as far as I > understand it the references do only get garbage-collected in case of > memory-pressure. > However, the behavior to keep recently used objects is only encouraged, not > explicitly required. > > Looking over the source code, you mabye can replace PageSource with a > custom implementation that uses another caching implementation. > Something like this (untested) code maybe? > > package tapestry; > > import java.lang.ref.SoftReference; > import java.util.Map; > > import org.apache.tapestry5.commons.util.CollectionFactory; > import org.apache.tapestry5.internal.services.PageLoader; > import org.apache.tapestry5.internal.services.PageSourceImpl; > import org.apache.tapestry5.internal.structure.Page; > import > org.apache.tapestry5.services.pageload.ComponentRequestSelectorAnalyzer; > import org.apache.tapestry5.services.pageload.ComponentResourceSelector; > > public class CustomPageSourceImpl extends PageSourceImpl { > > private PageLoader pageLoader; > private ComponentRequestSelectorAnalyzer selectorAnalyzer; > > public CustomPageSourceImpl(PageLoader pageLoader, > ComponentRequestSelectorAnalyzer selectorAnalyzer) { > super(pageLoader, selectorAnalyzer); > this.pageLoader = pageLoader; > this.selectorAnalyzer = selectorAnalyzer; > > } > > private static final record CachedPageKey(String pageName, > ComponentResourceSelector selector) { > } > > private final Map<CachedPageKey, Object> pageCache = > CollectionFactory.newConcurrentMap(); > > public Page getPage(String canonicalPageName) > { > var selector = selectorAnalyzer.buildSelectorForRequest(); > > var key = new CachedPageKey(canonicalPageName, selector); > > while (true) > { > Object cachedObject = pageCache.get(key); > > Page page = null; > if (cachedObject instanceof SoftReference<?> ref) { > page = ref == null ? null : (Page) ref.get(); > } else { > page = (Page) cachedObject; > } > > if (page != null) > { > return page; > } > // In rare race conditions, we may see the same page loaded > multiple times across > // different threads. The last built one will "evict" the > others from the page cache, > // and the earlier ones will be GCed. > > page = pageLoader.loadPage(canonicalPageName, selector); > > // TODO: Decide here if how you want to store the Page > > Object cacheValue = new SoftReference<Page>(page); > > pageCache.put(key, cacheValue); > } > } > } > > I'm not sure what the implications are if a page is kept forever, but as a > SoftReference isn't guaranteed to be garbage-collected, I don't see an > immediate downside, except needing more memory. > > Alternatively you could trigger the page with a cron job to keep it > "fresh", but an overriden service is the more robust solution in my opinion. > > Cheers > Ben > > On Tue, Dec 27, 2022 at 3:24 PM JumpStart < > geoff.callender.jumpst...@gmail.com> wrote: > >> Hi, >> >> I have one page in my production app which takes a long time to load - >> minimum 18 seconds. Once loaded, it is very quick to request. But from time >> to time throughout the day, when this page is requested Tapestry decides it >> has to reload it. I presume this is because the page cache uses >> SoftReference (PageSourceImpl.pageCache) and the page has been garbage >> collected. For the unlucky user, they have to wait an unbearably long time. >> Sometimes when the system is under load the request can even time out. Is >> there a simple, reliable, safe way to prevent it being garbage collected? >> Or have I misunderstood what’s going on? >> >> Cheers, >> >> Geoff >> >> >> --------------------------------------------------------------------- >> To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org >> For additional commands, e-mail: users-h...@tapestry.apache.org >> >> --------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscr...@tapestry.apache.org For additional commands, e-mail: users-h...@tapestry.apache.org