- Add a periodic tick for Jasper (other servlets could use it).
authorremm <remm@13f79535-47bb-0310-9956-ffa450edef68>
Wed, 27 Sep 2006 13:05:35 +0000 (13:05 +0000)
committerremm <remm@13f79535-47bb-0310-9956-ffa450edef68>
Wed, 27 Sep 2006 13:05:35 +0000 (13:05 +0000)
- Remove the dedicated thread that was used by each Jasper instance for checking for recompilation.

git-svn-id: https://svn.apache.org/repos/asf/tomcat/tc6.0.x/trunk@450424 13f79535-47bb-0310-9956-ffa450edef68

java/org/apache/PeriodicEventListener.java [new file with mode: 0644]
java/org/apache/catalina/core/StandardWrapper.java
java/org/apache/jasper/compiler/JspRuntimeContext.java
java/org/apache/jasper/servlet/JspServlet.java

diff --git a/java/org/apache/PeriodicEventListener.java b/java/org/apache/PeriodicEventListener.java
new file mode 100644 (file)
index 0000000..08d6c3f
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache;
+
+public interface PeriodicEventListener {
+    /**
+     * Execute a periodic task, such as reloading, etc.
+     */
+    public void periodicEvent();
+}
index cedf300..b0756ff 100644 (file)
@@ -47,6 +47,7 @@ import javax.management.NotificationFilter;
 import javax.management.NotificationListener;
 import javax.management.ObjectName;
 
+import org.apache.PeriodicEventListener;
 import org.apache.catalina.Container;
 import org.apache.catalina.ContainerServlet;
 import org.apache.catalina.Context;
@@ -652,6 +653,23 @@ public class StandardWrapper
 
 
     /**
+     * Execute a periodic task, such as reloading, etc. This method will be
+     * invoked inside the classloading context of this container. Unexpected
+     * throwables will be caught and logged.
+     */
+    public void backgroundProcess() {
+        super.backgroundProcess();
+        
+        if (!started)
+            return;
+        
+        if (getServlet() != null && (getServlet() instanceof PeriodicEventListener)) {
+            ((PeriodicEventListener) getServlet()).periodicEvent();
+        }
+    }
+    
+    
+    /**
      * Extract the root cause from a servlet exception.
      * 
      * @param e The servlet exception
index 5df34dd..f8e0911 100644 (file)
@@ -25,8 +25,6 @@ import java.security.CodeSource;
 import java.security.PermissionCollection;
 import java.security.Policy;
 import java.security.cert.Certificate;
-import java.util.Collections;
-import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
@@ -56,7 +54,7 @@ import org.apache.jasper.servlet.JspServletWrapper;
  * @author Glenn L. Nielsen
  * @version $Revision: 306189 $
  */
-public final class JspRuntimeContext implements Runnable {
+public final class JspRuntimeContext {
 
     // Logger
     private Log log = LogFactory.getLog(JspRuntimeContext.class);
@@ -124,13 +122,7 @@ public final class JspRuntimeContext implements Runnable {
         if (!options.getDevelopment()
                 && appBase != null
                 && options.getCheckInterval() > 0) {
-            if (appBase.endsWith(File.separator) ) {
-                appBase = appBase.substring(0,appBase.length()-1);
-            }
-            String directory =
-                appBase.substring(appBase.lastIndexOf(File.separator));
-            threadName = threadName + "[" + directory + "]";
-            threadStart();
+            lastCheck = System.currentTimeMillis();
         }                                            
     }
 
@@ -145,6 +137,7 @@ public final class JspRuntimeContext implements Runnable {
     private PermissionCollection permissionCollection;
     private CodeSource codeSource;                    
     private String classpath;
+    private long lastCheck = -1L;
 
     /**
      * Maps JSP pages to their JspServletWrapper's
@@ -152,23 +145,6 @@ public final class JspRuntimeContext implements Runnable {
     private Map<String, JspServletWrapper> jsps = new ConcurrentHashMap<String, JspServletWrapper>();
  
 
-    /**
-     * The background thread.
-     */
-    private Thread thread = null;
-
-
-    /**
-     * The background thread completion semaphore.
-     */
-    private boolean threadDone = false;
-
-
-    /**
-     * Name to register for the background thread.
-     */
-    private String threadName = "JspRuntimeContext";
-
     // ------------------------------------------------------ Public Methods
 
     /**
@@ -243,8 +219,6 @@ public final class JspRuntimeContext implements Runnable {
      * Process a "destory" event for this web application context.
      */                                                        
     public void destroy() {
-        threadStop();
-
         Iterator servlets = jsps.values().iterator();
         while (servlets.hasNext()) {
             ((JspServletWrapper) servlets.next()).destroy();
@@ -277,13 +251,23 @@ public final class JspRuntimeContext implements Runnable {
     }
 
 
-    // -------------------------------------------------------- Private Methods
-
     /**
      * Method used by background thread to check the JSP dependencies
      * registered with this class for JSP's.
      */
-    private void checkCompile() {
+    public void checkCompile() {
+
+        if (lastCheck < 0) {
+            // Checking was disabled
+            return;
+        }
+        long now = System.currentTimeMillis();
+        if (now > (lastCheck + (options.getCheckInterval() * 1000L))) {
+            lastCheck = now;
+        } else {
+            return;
+        }
+        
         Object [] wrappers = jsps.values().toArray();
         for (int i = 0; i < wrappers.length; i++ ) {
             JspServletWrapper jsw = (JspServletWrapper)wrappers[i];
@@ -301,6 +285,7 @@ public final class JspRuntimeContext implements Runnable {
                 }
             }
         }
+
     }
 
     /**
@@ -310,6 +295,10 @@ public final class JspRuntimeContext implements Runnable {
         return classpath;
     }
 
+
+    // -------------------------------------------------------- Private Methods
+
+
     /**
      * Method used to initialize classpath for compiles.
      */
@@ -433,92 +422,4 @@ public final class JspRuntimeContext implements Runnable {
     }
 
 
-    // -------------------------------------------------------- Thread Support
-
-    /**
-     * Start the background thread that will periodically check for
-     * changes to compile time included files in a JSP.
-     *
-     * @exception IllegalStateException if we should not be starting
-     *  a background thread now
-     */
-    protected void threadStart() {
-
-        // Has the background thread already been started?
-        if (thread != null) {
-            return;
-        }
-
-        // Start the background thread
-        threadDone = false;
-        thread = new Thread(this, threadName);
-        thread.setDaemon(true);
-        thread.start();
-
-    }
-
-
-    /**
-     * Stop the background thread that is periodically checking for
-     * changes to compile time included files in a JSP.
-     */ 
-    protected void threadStop() {
-
-        if (thread == null) {
-            return;
-        }
-
-        threadDone = true;
-        thread.interrupt();
-        try {
-            thread.join();
-        } catch (InterruptedException e) {
-            ;
-        }
-        
-        thread = null;
-        
-    }
-
-    /**
-     * Sleep for the duration specified by the <code>checkInterval</code>
-     * property.
-     */ 
-    protected void threadSleep() {
-        
-        try {
-            Thread.sleep(options.getCheckInterval() * 1000L);
-        } catch (InterruptedException e) {
-            ;
-        }
-        
-    }   
-    
-    
-    // ------------------------------------------------------ Background Thread
-        
-        
-    /**
-     * The background thread that checks for changes to files
-     * included by a JSP and flags that a recompile is required.
-     */ 
-    public void run() {
-        
-        // Loop until the termination semaphore is set
-        while (!threadDone) {
-
-            // Wait for our check interval
-            threadSleep();
-
-            // Check for included files which are newer than the
-            // JSP which uses them.
-            try {
-                checkCompile();
-            } catch (Throwable t) {
-                log.error("Exception checking if recompile needed: ", t);
-            }
-        }
-        
-    }
-
 }
index 82e5f5e..b9acb43 100644 (file)
@@ -27,6 +27,7 @@ import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
+import org.apache.PeriodicEventListener;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
@@ -52,7 +53,7 @@ import org.apache.jasper.compiler.Localizer;
  * @author Kin-man Chung
  * @author Glenn Nielsen
  */
-public class JspServlet extends HttpServlet {
+public class JspServlet extends HttpServlet implements PeriodicEventListener {
 
     // Logger
     private Log log = LogFactory.getLog(JspServlet.class);
@@ -283,6 +284,10 @@ public class JspServlet extends HttpServlet {
     }
 
 
+    public void periodicEvent() {
+        rctxt.checkCompile();
+    }
+
     // -------------------------------------------------------- Private Methods
 
     private void serviceJspFile(HttpServletRequest request,
@@ -315,4 +320,5 @@ public class JspServlet extends HttpServlet {
 
     }
 
+
 }