From: rjung Date: Fri, 29 Oct 2010 23:22:35 +0000 (+0000) Subject: Add new JSP init parameter "jspIdleTimeout". X-Git-Url: https://git.internetallee.de/?a=commitdiff_plain;h=770bea999e4b5cf9287957b699ece9e8555a1ee5;p=tomcat7.0 Add new JSP init parameter "jspIdleTimeout". If set > 0 (default -1), a background task will unload all JSPs being idle longer than this time in seconds. git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@1028940 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/java/org/apache/jasper/EmbeddedServletOptions.java b/java/org/apache/jasper/EmbeddedServletOptions.java index 72d41d83e..f1fdaa9aa 100644 --- a/java/org/apache/jasper/EmbeddedServletOptions.java +++ b/java/org/apache/jasper/EmbeddedServletOptions.java @@ -189,11 +189,17 @@ public final class EmbeddedServletOptions implements Options { /** - * The maxim number of loaded jsps per web-application. If there are more + * The maximum number of loaded jsps per web-application. If there are more * jsps loaded, they will be unloaded. */ private int maxLoadedJsps = -1; + /** + * The idle time after which a JSP is unloaded. + * If unset or less or equal than 0, no jsps are unloaded. + */ + private int jspIdleTimeout = -1; + public String getProperty(String name ) { return settings.getProperty( name ); } @@ -391,14 +397,22 @@ public final class EmbeddedServletOptions implements Options { } /** - * Should any jsps be unloaded? If set to a value greater than 0 eviction of jsps - * is started. Default: -1 - * */ + * Should jsps be unloaded if to many are loaded? + * If set to a value greater than 0 eviction of jsps is started. Default: -1 + */ public int getMaxLoadedJsps() { return maxLoadedJsps; } /** + * Should any jsps be unloaded when being idle for to long? + * If set to a value greater than 0 eviction of jsps is started. Default: -1 + */ + public int getJspIdleTimeout() { + return jspIdleTimeout; + } + + /** * Create an EmbeddedServletOptions object using data available from * ServletConfig and ServletContext. */ @@ -689,6 +703,17 @@ public final class EmbeddedServletOptions implements Options { } } } + + String jspIdleTimeout = config.getInitParameter("jspIdleTimeout"); + if (jspIdleTimeout != null) { + try { + this.jspIdleTimeout = Integer.parseInt(jspIdleTimeout); + } catch(NumberFormatException ex) { + if (log.isWarnEnabled()) { + log.warn(Localizer.getMessage("jsp.warning.jspIdleTimeout", ""+this.jspIdleTimeout)); + } + } + } // Setup the global Tag Libraries location cache for this // web-application. diff --git a/java/org/apache/jasper/JspC.java b/java/org/apache/jasper/JspC.java index 150eb4483..a1e03c5f3 100644 --- a/java/org/apache/jasper/JspC.java +++ b/java/org/apache/jasper/JspC.java @@ -447,6 +447,10 @@ public class JspC implements Options { return -1; } + public int getJspIdleTimeout() { + return -1; + } + /** * {@inheritDoc} */ diff --git a/java/org/apache/jasper/Options.java b/java/org/apache/jasper/Options.java index f7372feb5..b30d04607 100644 --- a/java/org/apache/jasper/Options.java +++ b/java/org/apache/jasper/Options.java @@ -222,9 +222,15 @@ public interface Options { public Map getCache(); /** - * The maxim number of loaded jsps per web-application. If there are more + * The maximum number of loaded jsps per web-application. If there are more * jsps loaded, they will be unloaded. If unset or less than 0, no jsps * are unloaded. */ public int getMaxLoadedJsps(); + + /** + * The idle time after which a JSP is unloaded. + * If unset or less or equal than 0, no jsps are unloaded. + */ + public int getJspIdleTimeout(); } diff --git a/java/org/apache/jasper/compiler/JspRuntimeContext.java b/java/org/apache/jasper/compiler/JspRuntimeContext.java index dff058a84..2cb08d253 100644 --- a/java/org/apache/jasper/compiler/JspRuntimeContext.java +++ b/java/org/apache/jasper/compiler/JspRuntimeContext.java @@ -160,6 +160,7 @@ public final class JspRuntimeContext { jspQueue = new FastRemovalDequeue(options.getMaxLoadedJsps()); } + jspIdleTimeout = options.getJspIdleTimeout() * 1000; } // ----------------------------------------------------- Instance Variables @@ -175,6 +176,7 @@ public final class JspRuntimeContext { private final String classpath; private volatile long lastCompileCheck = -1L; private volatile long lastJspQueueUpdate = System.currentTimeMillis(); + private long jspIdleTimeout; /** * Maps JSP pages to their JspServletWrapper's @@ -527,6 +529,22 @@ public final class JspRuntimeContext { */ public void checkUnload() { - lastJspQueueUpdate = System.currentTimeMillis(); + long now = System.currentTimeMillis(); + if (jspIdleTimeout > 0) { + long unloadBefore = now - jspIdleTimeout; + Object [] wrappers = jsps.values().toArray(); + for (int i = 0; i < wrappers.length; i++ ) { + JspServletWrapper jsw = (JspServletWrapper)wrappers[i]; + synchronized(jsw) { + if (jsw.getLastUsageTime() < unloadBefore) { + if (jspQueue != null) { + jspQueue.remove(jsw.getUnloadHandle()); + } + unloadJspServletWrapper(jsw); + } + } + } + } + lastJspQueueUpdate = now; } } diff --git a/java/org/apache/jasper/resources/LocalStrings.properties b/java/org/apache/jasper/resources/LocalStrings.properties index 11e07ec0a..616eea573 100644 --- a/java/org/apache/jasper/resources/LocalStrings.properties +++ b/java/org/apache/jasper/resources/LocalStrings.properties @@ -177,6 +177,7 @@ jsp.warning.genchararray=Warning: Invalid value for the initParam genStrAsCharAr jsp.warning.suppressSmap=Warning: Invalid value for the initParam suppressSmap. Will use the default value of \"false\" jsp.warning.displaySourceFragment=Warning: Invalid value for the initParam displaySourceFragment. Will use the default value of \"true\" jsp.warning.maxLoadedJsps=Warning: Invalid value for the initParam maxLoadedJsps. Will use the default value of \"-1\" +jsp.warning.jspIdleTimeout=Warning: Invalid value for the initParam jspIdleTimeout. Will use the default value of \"-1\" jsp.error.badtaglib=Unable to open taglibrary {0} : {1} jsp.error.badGetReader=Cannot create a reader when the stream is not buffered jsp.warning.unknown.element.in.taglib=Unknown element ({0}) in taglib @@ -470,4 +471,4 @@ jsp.warning.noJarScanner=Warning: No org.apache.tomcat.JarScanner set in Servlet jsp.error.bug48498=Unable to display JSP extract. Probably due to an XML parser bug (see Tomcat bug 48498 for details). # UniqueAttributesImpl -jsp.error.duplicateqname=An attribute with duplicate qualified name [{0}] was found. Attribute qualified names must be unique within an element. \ No newline at end of file +jsp.error.duplicateqname=An attribute with duplicate qualified name [{0}] was found. Attribute qualified names must be unique within an element. diff --git a/java/org/apache/jasper/servlet/JspServletWrapper.java b/java/org/apache/jasper/servlet/JspServletWrapper.java index 6a6867296..66738a2ea 100644 --- a/java/org/apache/jasper/servlet/JspServletWrapper.java +++ b/java/org/apache/jasper/servlet/JspServletWrapper.java @@ -89,7 +89,9 @@ public class JspServletWrapper { private long lastModificationTest = 0L; private long lastUsageTime = System.currentTimeMillis(); private FastRemovalDequeue.Entry unloadHandle; + private final boolean unloadAllowed; private final boolean unloadByCount; + private final boolean unloadByIdle; /* * JspServletWrapper for JSP pages. @@ -102,6 +104,8 @@ public class JspServletWrapper { this.options = options; this.jspUri = jspUri; unloadByCount = options.getMaxLoadedJsps() > 0 ? true : false; + unloadByIdle = options.getJspIdleTimeout() > 0 ? true : false; + unloadAllowed = unloadByCount || unloadByIdle ? true : false; ctxt = new JspCompilationContext(jspUri, isErrorPage, options, config.getServletContext(), this, rctxt); @@ -123,6 +127,8 @@ public class JspServletWrapper { this.jspUri = tagFilePath; this.tripCount = 0; unloadByCount = options.getMaxLoadedJsps() > 0 ? true : false; + unloadByIdle = options.getJspIdleTimeout() > 0 ? true : false; + unloadAllowed = unloadByCount || unloadByIdle ? true : false; ctxt = new JspCompilationContext(jspUri, tagInfo, options, servletContext, this, rctxt, tagJarResource); @@ -296,6 +302,10 @@ public class JspServletWrapper { return jspUri; } + public FastRemovalDequeue.Entry getUnloadHandle() { + return unloadHandle; + } + public void service(HttpServletRequest request, HttpServletResponse response, boolean precompile) @@ -377,13 +387,19 @@ public class JspServletWrapper { /* * (3) Handle limitation of number of loaded Jsps */ - if (unloadByCount) { + if (unloadAllowed) { synchronized(this) { - if (unloadHandle == null) { - unloadHandle = ctxt.getRuntimeContext().push(this); - } else if (lastUsageTime < ctxt.getRuntimeContext().getLastJspQueueUpdate()) { - ctxt.getRuntimeContext().makeYoungest(unloadHandle); - lastUsageTime = System.currentTimeMillis(); + if (unloadByCount) { + if (unloadHandle == null) { + unloadHandle = ctxt.getRuntimeContext().push(this); + } else if (lastUsageTime < ctxt.getRuntimeContext().getLastJspQueueUpdate()) { + ctxt.getRuntimeContext().makeYoungest(unloadHandle); + lastUsageTime = System.currentTimeMillis(); + } + } else { + if (lastUsageTime < ctxt.getRuntimeContext().getLastJspQueueUpdate()) { + lastUsageTime = System.currentTimeMillis(); + } } } } @@ -469,6 +485,13 @@ public class JspServletWrapper { } /** + * @return the lastUsageTime. + */ + public long getLastUsageTime() { + return lastUsageTime; + } + + /** *

Attempts to construct a JasperException that contains helpful information * about what went wrong. Uses the JSP compiler system to translate the line * number in the generated servlet that originated the exception to a line