Author: sshafroi
Date: 2008-06-10 12:01:45 +0200 (Tue, 10 Jun 2008)
New Revision: 6684

Modified:
   trunk/war/src/main/java/no/sesat/search/http/filters/SiteLocatorFilter.java
Log:
Issue SKER4321: (Load reducing filter that handles only current and last 
request from client)

Implementation:

- A request comes inn, if there is less then max number on the stack then push 
it, else return 409. (max number = 5)
- If the current thread's request is the same request as the one at the top of 
the stack, then execute it. If not then wait for a minimum time to see if our 
request is at the top of the stack. If this is not the case we return a 409. 
(timeout = 5000ms)



Modified: 
trunk/war/src/main/java/no/sesat/search/http/filters/SiteLocatorFilter.java
===================================================================
--- trunk/war/src/main/java/no/sesat/search/http/filters/SiteLocatorFilter.java 
2008-06-10 08:18:44 UTC (rev 6683)
+++ trunk/war/src/main/java/no/sesat/search/http/filters/SiteLocatorFilter.java 
2008-06-10 10:01:45 UTC (rev 6684)
@@ -30,13 +30,9 @@
 import java.util.Enumeration;
 import java.util.Locale;
 import java.util.Properties;
+import java.util.Stack;
 import java.util.UUID;
 import java.text.MessageFormat;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantLock;
-import javax.enterprise.deploy.model.J2eeApplicationObject;
-import javax.enterprise.deploy.model.J2eeApplicationObject;
 import javax.servlet.Filter;
 import javax.servlet.FilterChain;
 import javax.servlet.FilterConfig;
@@ -55,8 +51,8 @@
 import no.sesat.search.site.config.UrlResourceLoader;
 import no.sesat.search.site.Site;
 import no.sesat.search.datamodel.DataModel;
-import no.sesat.search.site.config.ResourceLoadException;
 import no.sesat.search.view.FindResource;
+
 import org.apache.commons.lang.StringEscapeUtils;
 import org.apache.commons.lang.time.StopWatch;
 import org.apache.log4j.Logger;
@@ -89,7 +85,11 @@
 
     private static final String UNKNOWN = "unknown";
 
+    private static final String USER_REQUEST_STACK = "userRequestStack";
+    private static final long WAIT_TIME = 5000;
+    private static final int REQUEST_QUEUE_SIZE = 5;
 
+
     // Any request coming into Sesat with /conf/ is immediately returned as a 
404.
     // It should have been directed to a skin.
     private static final String CONFIGURATION_RESOURCE= "/conf/";
@@ -385,44 +385,50 @@
     // Protected -----------------------------------------------------
 
     // Private -------------------------------------------------------
+    private static void doChainFilter(final FilterChain chain, final 
ServletRequest request,
+            final ServletResponse response) throws IOException, 
ServletException {
+        if (request instanceof HttpServletRequest) {
+            HttpSession session = ((HttpServletRequest) request).getSession();
 
-    private static void doChainFilter(
-            final FilterChain chain,
-            final ServletRequest request,
-            final ServletResponse response) throws IOException, 
ServletException{
+            Stack<ServletRequest> stack = (Stack<ServletRequest>) 
session.getAttribute(USER_REQUEST_STACK);
+            if (null == stack) {
+                stack = new Stack<ServletRequest>();
+                session.setAttribute(USER_REQUEST_STACK, stack);
+            }
 
-        Lock lock = request instanceof HttpServletRequest
-                ? (Lock) 
((HttpServletRequest)request).getSession().getAttribute("userLock")
-                : new ReentrantLock();
+            if (stack.size() > REQUEST_QUEUE_SIZE) {
+                if (response instanceof HttpServletResponse) {
+                    LOG.warn(" -- response 409 (More then " + 
REQUEST_QUEUE_SIZE + " request in queue)");
+                    ((HttpServletResponse) 
response).sendError(HttpServletResponse.SC_CONFLICT);
+                }
+            } else {
+                stack.push(request);
 
-        if(null == lock){
-            lock = new ReentrantLock();
-            
((HttpServletRequest)request).getSession().setAttribute("userLock", lock);
-        }
-
-        // datamodel is NOT request-safe. all the user's requests must execute 
in sequence!
-        //  ten seconds is enough to wait.
-        boolean done = false;
-        try{
-            if( lock.tryLock(10, TimeUnit.SECONDS) ){
-                try{
-                    // request will be processed by search-portal
-                    LOG.info("Incoming! Duck!");
-                    chain.doFilter(request, response);
-                    done = true;
-                }finally{
-                    lock.unlock();
+                long start = System.currentTimeMillis();
+                synchronized (session) {
+                    long timeLeft = WAIT_TIME - (System.currentTimeMillis() - 
start);
+                    while (stack.peek() != request && timeLeft > 0) {
+                        try {
+                            session.wait(timeLeft);
+                            timeLeft = WAIT_TIME - (System.currentTimeMillis() 
- start);
+                        } catch (InterruptedException e) {
+                            LOG.error(e);
+                            timeLeft = -1;
+                        }
+                    }
+                    if (timeLeft >= 0) {
+                        chain.doFilter(request, response);
+                    } else {
+                        LOG.warn(" -- response 409 (Timeout: Waited " + 
(WAIT_TIME - timeLeft) + " ms. )");
+                        ((HttpServletResponse) 
response).sendError(HttpServletResponse.SC_CONFLICT);
+                    }
+                    stack.pop();
+                    session.notifyAll();
                 }
             }
-        }catch(InterruptedException ie){
-            LOG.warn("The duck got trucked", ie);
+        } else {
+            chain.doFilter(request, response);
         }
-
-        if(!done && response instanceof HttpServletResponse){
-            // failed to get lock in time
-            LOG.warn(" -- response 409");
-            
((HttpServletResponse)response).sendError(HttpServletResponse.SC_CONFLICT);
-        }
     }
 
     static String getRequestId(final ServletRequest servletRequest){
@@ -654,6 +660,5 @@
         public int getStatus(){
             return status;
         }
-
     }
 }

_______________________________________________
Kernel-commits mailing list
[email protected]
http://sesat.no/mailman/listinfo/kernel-commits

Reply via email to