From 884586d16eab1cc9bb5ea1efc637d3b27c42c025 Mon Sep 17 00:00:00 2001 From: fhanik Date: Fri, 9 Oct 2009 21:52:36 +0000 Subject: [PATCH] Just like filters, valves will have to be async aware in order for it to work properly. git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@823710 13f79535-47bb-0310-9956-ffa450edef68 --- java/org/apache/catalina/Pipeline.java | 6 ++++++ java/org/apache/catalina/Valve.java | 3 +++ java/org/apache/catalina/connector/CoyoteAdapter.java | 2 ++ java/org/apache/catalina/core/ContainerBase.java | 8 ++++++++ java/org/apache/catalina/core/StandardContextValve.java | 4 +++- java/org/apache/catalina/core/StandardEngineValve.java | 3 +++ java/org/apache/catalina/core/StandardHostValve.java | 4 ++++ java/org/apache/catalina/core/StandardPipeline.java | 15 +++++++++++---- java/org/apache/catalina/core/StandardWrapperValve.java | 2 +- java/org/apache/catalina/valves/ValveBase.java | 17 ++++++++++++++++- webapps/examples/jsp/async/index.jsp | 14 +++++++++++++- 11 files changed, 70 insertions(+), 8 deletions(-) diff --git a/java/org/apache/catalina/Pipeline.java b/java/org/apache/catalina/Pipeline.java index beb8fed51..d457115d5 100644 --- a/java/org/apache/catalina/Pipeline.java +++ b/java/org/apache/catalina/Pipeline.java @@ -116,6 +116,12 @@ public interface Pipeline { * Valve for this Pipeline (if any). */ public Valve getFirst(); + + /** + * Returns true if all the valves in this pipeline support async, false otherwise + * @return true if all the valves in this pipeline support async, false otherwise + */ + public boolean isAsyncSupported(); } diff --git a/java/org/apache/catalina/Valve.java b/java/org/apache/catalina/Valve.java index 858812dbe..414317032 100644 --- a/java/org/apache/catalina/Valve.java +++ b/java/org/apache/catalina/Valve.java @@ -144,5 +144,8 @@ public interface Valve { public void event(Request request, Response response, CometEvent event) throws IOException, ServletException; + + public boolean isAsyncSupported(); + } diff --git a/java/org/apache/catalina/connector/CoyoteAdapter.java b/java/org/apache/catalina/connector/CoyoteAdapter.java index 563aebb02..07139f9df 100644 --- a/java/org/apache/catalina/connector/CoyoteAdapter.java +++ b/java/org/apache/catalina/connector/CoyoteAdapter.java @@ -373,6 +373,8 @@ public class CoyoteAdapter // request parameters req.getRequestProcessor().setWorkerThreadName(Thread.currentThread().getName()); if (postParseRequest(req, request, res, response)) { + //check valves if we support async + request.setAsyncSupported(connector.getContainer().getPipeline().isAsyncSupported()); // Calling the container connector.getContainer().getPipeline().getFirst().invoke(request, response); diff --git a/java/org/apache/catalina/core/ContainerBase.java b/java/org/apache/catalina/core/ContainerBase.java index 5389ed561..4bdf41f68 100644 --- a/java/org/apache/catalina/core/ContainerBase.java +++ b/java/org/apache/catalina/core/ContainerBase.java @@ -1617,4 +1617,12 @@ public abstract class ContainerBase } + @Override + public boolean isAsyncSupported() { + return pipeline.isAsyncSupported(); + } + + + + } diff --git a/java/org/apache/catalina/core/StandardContextValve.java b/java/org/apache/catalina/core/StandardContextValve.java index 2d7eeced0..e6be2d8de 100644 --- a/java/org/apache/catalina/core/StandardContextValve.java +++ b/java/org/apache/catalina/core/StandardContextValve.java @@ -187,7 +187,9 @@ final class StandardContextValve } } } - + if (request.isAsyncSupported()) { + request.setAsyncSupported(wrapper.getPipeline().isAsyncSupported()); + } wrapper.getPipeline().getFirst().invoke(request, response); if ((instances !=null ) && diff --git a/java/org/apache/catalina/core/StandardEngineValve.java b/java/org/apache/catalina/core/StandardEngineValve.java index f62157536..b48d5f215 100644 --- a/java/org/apache/catalina/core/StandardEngineValve.java +++ b/java/org/apache/catalina/core/StandardEngineValve.java @@ -104,6 +104,9 @@ final class StandardEngineValve request.getServerName())); return; } + if (request.isAsyncSupported()) { + request.setAsyncSupported(host.getPipeline().isAsyncSupported()); + } // Ask this Host to process this request host.getPipeline().getFirst().invoke(request, response); diff --git a/java/org/apache/catalina/core/StandardHostValve.java b/java/org/apache/catalina/core/StandardHostValve.java index b4ac6eda3..32354ad11 100644 --- a/java/org/apache/catalina/core/StandardHostValve.java +++ b/java/org/apache/catalina/core/StandardHostValve.java @@ -123,6 +123,10 @@ final class StandardHostValve Thread.currentThread().setContextClassLoader (context.getLoader().getClassLoader()); } + if (request.isAsyncSupported()) { + request.setAsyncSupported(context.getPipeline().isAsyncSupported()); + } + // Ask this Context to process this request context.getPipeline().getFirst().invoke(request, response); diff --git a/java/org/apache/catalina/core/StandardPipeline.java b/java/org/apache/catalina/core/StandardPipeline.java index 5fc3874fd..bd48c87d4 100644 --- a/java/org/apache/catalina/core/StandardPipeline.java +++ b/java/org/apache/catalina/core/StandardPipeline.java @@ -128,8 +128,7 @@ public class StandardPipeline * The first valve associated with this Pipeline. */ protected Valve first = null; - - + // --------------------------------------------------------- Public Methods @@ -141,6 +140,16 @@ public class StandardPipeline return (this.info); } + + public boolean isAsyncSupported() { + Valve valve = (first!=null)?first:basic; + boolean supported = true; + while (supported && valve!=null) { + supported = supported & valve.isAsyncSupported(); + valve = valve.getNext(); + } + return supported; + } // ------------------------------------------------------ Contained Methods @@ -559,6 +568,4 @@ public class StandardPipeline return basic; } } - - } diff --git a/java/org/apache/catalina/core/StandardWrapperValve.java b/java/org/apache/catalina/core/StandardWrapperValve.java index d9dbc1bcf..3f8a2761f 100644 --- a/java/org/apache/catalina/core/StandardWrapperValve.java +++ b/java/org/apache/catalina/core/StandardWrapperValve.java @@ -199,7 +199,7 @@ final class StandardWrapperValve // Reset comet flag value after creating the filter chain request.setComet(false); //check filters to see if we support async or not. - if (filterChain != null) { + if (filterChain != null && request.isAsyncSupported()) { request.setAsyncSupported(filterChain.isAsyncSupported()); } diff --git a/java/org/apache/catalina/valves/ValveBase.java b/java/org/apache/catalina/valves/ValveBase.java index 54e2b7293..cbea0f15f 100644 --- a/java/org/apache/catalina/valves/ValveBase.java +++ b/java/org/apache/catalina/valves/ValveBase.java @@ -63,6 +63,11 @@ public abstract class ValveBase /** + * Does this valve support async reporting + */ + protected boolean asyncSupported = false; + + /** * The Container whose pipeline this Valve is a component of. */ protected Container container = null; @@ -97,7 +102,7 @@ public abstract class ValveBase //-------------------------------------------------------------- Properties - + /** * Return the Container with which this Valve is associated, if any. */ @@ -108,6 +113,16 @@ public abstract class ValveBase } + public boolean isAsyncSupported() { + return asyncSupported; + } + + + public void setAsyncSupported(boolean asyncSupported) { + this.asyncSupported = asyncSupported; + } + + /** * Set the Container with which this Valve is associated, if any. * diff --git a/webapps/examples/jsp/async/index.jsp b/webapps/examples/jsp/async/index.jsp index cb784b5ad..bd3efaeb5 100644 --- a/webapps/examples/jsp/async/index.jsp +++ b/webapps/examples/jsp/async/index.jsp @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. --> -<%@page session="false"%> +%@page session="false"%>
 Use cases:
@@ -50,4 +50,16 @@ Use cases:
  - servlet does a setAsyncTimeout
  - servlet does a addAsyncListener
  - returns - waits for timeout to happen and listener invoked 
+ 
+5. Dispatch to asyncSupported=false servlet
+ - servlet1 does a startAsync()
+ - servlet1 dispatches to dispatch(/servlet2)
+ - the container calls complete() after servlet2 is complete
+ - TODO
+ 
+6. Chained dispatch
+ - servlet1 does a startAsync
+ - servlet1 does a dispatch to servlet2 (asyncsupported=true)
+ - servlet2 does a dispatch to servlet3 (asyncsupported=true)
+ - servlet3 does a dispatch to servlet4 (asyncsupported=false) 
 
\ No newline at end of file -- 2.11.0