Author: fhanik Date: Wed Jul 15 00:33:14 2009 New Revision: 794122 URL: http://svn.apache.org/viewvc?rev=794122&view=rev Log: Start working on async, fairly similar to comet but much more convulated. I'm gonna do checkins in fairly small chunks so folks can tag along and help out. Instead of doing one giant checkin
Added: tomcat/trunk/java/org/apache/catalina/connector/AsyncContextImpl.java (with props) tomcat/trunk/java/org/apache/catalina/connector/AsyncListenerWrapper.java (with props) Modified: tomcat/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java tomcat/trunk/java/org/apache/catalina/connector/Request.java tomcat/trunk/java/org/apache/catalina/deploy/FilterDef.java tomcat/trunk/java/org/apache/catalina/startup/WebRuleSet.java tomcat/trunk/java/org/apache/coyote/ActionCode.java tomcat/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java tomcat/trunk/java/org/apache/coyote/http11/Http11Processor.java Added: tomcat/trunk/java/org/apache/catalina/connector/AsyncContextImpl.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/connector/AsyncContextImpl.java?rev=794122&view=auto ============================================================================== --- tomcat/trunk/java/org/apache/catalina/connector/AsyncContextImpl.java (added) +++ tomcat/trunk/java/org/apache/catalina/connector/AsyncContextImpl.java Wed Jul 15 00:33:14 2009 @@ -0,0 +1,161 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.catalina.connector; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import javax.servlet.AsyncContext; +import javax.servlet.AsyncListener; +import javax.servlet.ServletContext; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; + +import org.apache.juli.logging.Log; +import org.apache.juli.logging.LogFactory; +/** + * + * @author fhanik + * + */ +public class AsyncContextImpl implements AsyncContext { + protected static Log log = LogFactory.getLog(AsyncContextImpl.class); + + private boolean started = false; + private ServletRequest servletRequest = null; + private ServletResponse servletResponse = null; + private List<AsyncListenerWrapper> listeners = new ArrayList<AsyncListenerWrapper>(); + private boolean hasOriginalRequestAndResponse = true; + + public AsyncContextImpl() { + //TODO SERVLET3 - async + } + + @Override + public void complete() { + // TODO SERVLET3 - async + + for (AsyncListenerWrapper wrapper : listeners) { + try { + wrapper.fireOnComplete(); + }catch (IOException x) { + //how does this propagate, or should it? + //TODO SERVLET3 - async + log.error("",x); + } + } + + } + + @Override + public void dispatch() { + // TODO SERVLET3 - async + + } + + @Override + public void dispatch(String path) { + // TODO SERVLET3 - async + + } + + @Override + public void dispatch(ServletContext context, String path) { + // TODO SERVLET3 - async + + } + + @Override + public ServletRequest getRequest() { + return getServletRequest(); + } + + @Override + public ServletResponse getResponse() { + return getServletResponse(); + } + + @Override + public void start(Runnable run) { + // TODO SERVLET3 - async + + } + + public void addAsyncListener(AsyncListener listener) { + AsyncListenerWrapper wrapper = new AsyncListenerWrapper(); + wrapper.setListener(listener); + wrapper.setServletRequest(getServletRequest()); + wrapper.setServletResponse(getServletResponse()); + listeners.add(wrapper); + } + + public void addAsyncListener(AsyncListener listener, ServletRequest servletRequest, ServletResponse servletResponse) { + AsyncListenerWrapper wrapper = new AsyncListenerWrapper(); + wrapper.setListener(listener); + wrapper.setServletRequest(servletRequest); + wrapper.setServletResponse(servletResponse); + listeners.add(wrapper); + } + + + protected void recycle() { + started = false; + servletRequest = null; + servletResponse = null; + listeners.clear(); + hasOriginalRequestAndResponse = true; + } + + public boolean isStarted() { + return started; + } + + public void setStarted(boolean started) { + this.started = started; + } + + public ServletRequest getServletRequest() { + return servletRequest; + } + + public void setServletRequest(ServletRequest servletRequest) { + this.servletRequest = servletRequest; + } + + public ServletResponse getServletResponse() { + return servletResponse; + } + + public void setServletResponse(ServletResponse servletResponse) { + this.servletResponse = servletResponse; + } + + @Override + public boolean hasOriginalRequestAndResponse() { + return hasOriginalRequestAndResponse; + } + + public void setHasOriginalRequestAndResponse(boolean hasOriginalRequestAndResponse) { + this.hasOriginalRequestAndResponse = hasOriginalRequestAndResponse; + } + + + + + +} Propchange: tomcat/trunk/java/org/apache/catalina/connector/AsyncContextImpl.java ------------------------------------------------------------------------------ svn:eol-style = native Added: tomcat/trunk/java/org/apache/catalina/connector/AsyncListenerWrapper.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/connector/AsyncListenerWrapper.java?rev=794122&view=auto ============================================================================== --- tomcat/trunk/java/org/apache/catalina/connector/AsyncListenerWrapper.java (added) +++ tomcat/trunk/java/org/apache/catalina/connector/AsyncListenerWrapper.java Wed Jul 15 00:33:14 2009 @@ -0,0 +1,72 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You 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.catalina.connector; + +import java.io.IOException; + +import javax.servlet.AsyncListener; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +/** + * TODO SERVLET 3 - async + * @author fhanik + * + */ +public class AsyncListenerWrapper { + + private AsyncListener listener = null; + private ServletRequest servletRequest = null; + private ServletResponse servletResponse = null; + + public void fireOnComplete() throws IOException { + // TODO SERVLET 3 - async + + } + + + public void fireOnTimeout() throws IOException { + // TODO SERVLET 3 - async + + } + + public ServletRequest getServletRequest() { + return servletRequest; + } + + public void setServletRequest(ServletRequest servletRequest) { + this.servletRequest = servletRequest; + } + + public ServletResponse getServletResponse() { + return servletResponse; + } + + public void setServletResponse(ServletResponse servletResponse) { + this.servletResponse = servletResponse; + } + + public AsyncListener getListener() { + return listener; + } + + public void setListener(AsyncListener listener) { + this.listener = listener; + } + + + +} Propchange: tomcat/trunk/java/org/apache/catalina/connector/AsyncListenerWrapper.java ------------------------------------------------------------------------------ svn:eol-style = native Modified: tomcat/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java?rev=794122&r1=794121&r2=794122&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java (original) +++ tomcat/trunk/java/org/apache/catalina/connector/CoyoteAdapter.java Wed Jul 15 00:33:14 2009 @@ -319,7 +319,10 @@ } - if (!comet) { + if (request.isAsyncStarted()) { + //TODO SERVLET3 - async + res.action(ActionCode.ACTION_ASYNC_START, request.getAsyncContext()); + } else if (!comet) { response.finishResponse(); req.action(ActionCode.ACTION_POST_REQUEST , null); } Modified: tomcat/trunk/java/org/apache/catalina/connector/Request.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/connector/Request.java?rev=794122&r1=794121&r2=794122&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/connector/Request.java (original) +++ tomcat/trunk/java/org/apache/catalina/connector/Request.java Wed Jul 15 00:33:14 2009 @@ -23,6 +23,7 @@ import java.io.IOException; import java.io.BufferedReader; import java.io.UnsupportedEncodingException; +import java.nio.channels.IllegalSelectorException; import java.security.Principal; import java.text.SimpleDateFormat; import java.util.ArrayList; @@ -387,10 +388,29 @@ * Local address */ protected String localName = null; - + + /** + * asyncSupported + */ + protected boolean asyncSupported = true; + + /** + * AsyncContext + */ + protected AsyncContextImpl asyncContext = null; + + /** + * async timeout + */ + protected long asyncTimeout = 0; // --------------------------------------------------------- Public Methods + + + public void setAsyncSupported(boolean asyncSupported) { + this.asyncSupported = asyncSupported; + } /** * Release all object references, and initialize instance variables, in @@ -464,6 +484,9 @@ reader = null; } } + + asyncSupported = true; + if (asyncContext!=null) asyncContext.recycle(); } @@ -1436,51 +1459,69 @@ } public AsyncContext startAsync() { - // TODO SERVLET3 - return null; - } - - public AsyncContext startAsync(ServletRequest request, - ServletResponse response) { - // TODO SERVLET3 - return null; + // TODO SERVLET3 - async + if (!isAsyncSupported()) throw new IllegalStateException("Not supported."); + if (asyncContext==null) asyncContext = new AsyncContextImpl(); + else if (asyncContext.isStarted()) throw new IllegalStateException("Already started."); + asyncContext.setServletRequest(getRequest()); + asyncContext.setServletResponse(response.getResponse()); + asyncContext.setStarted(true); + return asyncContext; + } + + public AsyncContext startAsync(ServletRequest request, ServletResponse response) { + startAsync(); + asyncContext.setServletRequest(request); + asyncContext.setServletResponse(response); + asyncContext.setHasOriginalRequestAndResponse(request==getRequest() && response==getResponse()); + return asyncContext; } public boolean isAsyncStarted() { - // TODO SERVLET3 - return false; + if (asyncContext==null) return false; + else return asyncContext.isStarted(); } public boolean isAsyncSupported() { - // TODO SERVLET3 - return false; + // TODO SERVLET3 - async + return this.asyncSupported; } public AsyncContext getAsyncContext() { - // TODO SERVLET3 - return null; + // TODO SERVLET3 - async + return this.asyncContext; } public void addAsyncListener(AsyncListener listener) { - // TODO SERVLET3 + // TODO SERVLET3 - async + if (isAsyncSupported() && isAsyncStarted()) { + this.asyncContext.addAsyncListener(listener); + } else { + throw new IllegalStateException("Async [Supported:"+isAsyncSupported()+"; Started:"+isAsyncStarted()+"]"); + } } - public void addAsyncListener(AsyncListener listener, - ServletRequest servletRequest, ServletResponse servletResponse) { - // TODO SERVLET3 + public void addAsyncListener(AsyncListener listener, ServletRequest servletRequest, ServletResponse servletResponse) { + // TODO SERVLET3 - async + if (isAsyncSupported() && isAsyncStarted()) { + this.asyncContext.addAsyncListener(listener,servletRequest,servletResponse); + } else { + throw new IllegalStateException("Async [Supported:"+isAsyncSupported()+"; Started:"+isAsyncStarted()+"]"); + } } public void setAsyncTimeout(long timeout) { - // TODO SERVLET3 + // TODO SERVLET3 - async + this.asyncTimeout = timeout; } public long getAsyncTimeout() { - // TODO SERVLET3 - return 0; + // TODO SERVLET3 - async + return asyncTimeout; } public DispatcherType getDispatcherType() { - // TODO SERVLET3 + // TODO SERVLET3 - dispatcher return null; } @@ -2241,26 +2282,26 @@ } public boolean authenticate(HttpServletResponse response) throws IOException { - // TODO Servlet 3 + // TODO Servlet 3 - authentication return false; } public void login(String username, String password) throws ServletException { - // TODO Servlet 3 + // TODO Servlet 3 - authentication } public void logout() throws ServletException { - // TODO Servlet 3 + // TODO Servlet 3 - authentication } public Iterable<Part> getParts() { - // TODO Servlet 3 + // TODO Servlet 3 - authentication return null; } public Part getPart(String name) throws IllegalArgumentException { - // TODO Servlet 3.0 + // TODO Servlet 3.0 - file upload return null; } Modified: tomcat/trunk/java/org/apache/catalina/deploy/FilterDef.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/deploy/FilterDef.java?rev=794122&r1=794121&r2=794122&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/deploy/FilterDef.java (original) +++ tomcat/trunk/java/org/apache/catalina/deploy/FilterDef.java Wed Jul 15 00:33:14 2009 @@ -134,6 +134,16 @@ public void setSmallIcon(String smallIcon) { this.smallIcon = smallIcon; } + + private boolean asyncSupported = false; + + public boolean isAsyncSupported() { + return asyncSupported; + } + + public void setAsyncSupported(boolean asyncSupported) { + this.asyncSupported = asyncSupported; + } // --------------------------------------------------------- Public Methods Modified: tomcat/trunk/java/org/apache/catalina/startup/WebRuleSet.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/startup/WebRuleSet.java?rev=794122&r1=794121&r2=794122&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/startup/WebRuleSet.java (original) +++ tomcat/trunk/java/org/apache/catalina/startup/WebRuleSet.java Wed Jul 15 00:33:14 2009 @@ -171,6 +171,11 @@ "setLargeIcon", 0); digester.addCallMethod(prefix + "web-app/filter/small-icon", "setSmallIcon", 0); + + //spec right now only has an annotation, not XML but we will add it + //TODO SERVLET3 - async + digester.addCallMethod(prefix + "web-app/filter/asyncSupported", + "setAsyncSupported", 0); digester.addCallMethod(prefix + "web-app/filter/init-param", "addInitParameter", 2); Modified: tomcat/trunk/java/org/apache/coyote/ActionCode.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/ActionCode.java?rev=794122&r1=794121&r2=794122&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/ActionCode.java (original) +++ tomcat/trunk/java/org/apache/coyote/ActionCode.java Wed Jul 15 00:33:14 2009 @@ -161,6 +161,21 @@ */ public static final ActionCode ACTION_COMET_SETTIMEOUT = new ActionCode(25); + /** + * Callback for an async request + */ + public static final ActionCode ACTION_ASYNC_START = new ActionCode(26); + + /** + * Callback for an async call to {...@link javax.servlet.AsyncContext#complete()} + */ + public static final ActionCode ACTION_ASYNC_COMPLETE = new ActionCode(27); + /** + * Callback for an async call to {...@link javax.servlet.ServletRequest#setAsyncTimeout(long)} + */ + public static final ActionCode ACTION_ASYNC_SETTIMEOUT = new ActionCode(28); + + // ----------------------------------------------------------- Constructors int code; Modified: tomcat/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java?rev=794122&r1=794121&r2=794122&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java Wed Jul 15 00:33:14 2009 @@ -1201,7 +1201,14 @@ //no op } else if (actionCode == ActionCode.ACTION_COMET_SETTIMEOUT) { //no op + } else if (actionCode == ActionCode.ACTION_ASYNC_START) { + //TODO SERVLET3 - async + } else if (actionCode == ActionCode.ACTION_ASYNC_COMPLETE) { + //TODO SERVLET3 - async + } else if (actionCode == ActionCode.ACTION_ASYNC_SETTIMEOUT) { + //TODO SERVLET3 - async } + } Modified: tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java?rev=794122&r1=794121&r2=794122&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java Wed Jul 15 00:33:14 2009 @@ -1238,6 +1238,12 @@ RequestInfo rp = request.getRequestProcessor(); if ( rp.getStage() != org.apache.coyote.Constants.STAGE_SERVICE ) //async handling attach.setTimeout(timeout); + } else if (actionCode == ActionCode.ACTION_ASYNC_START) { + //TODO SERVLET3 - async + } else if (actionCode == ActionCode.ACTION_ASYNC_COMPLETE) { + //TODO SERVLET3 - async + } else if (actionCode == ActionCode.ACTION_ASYNC_SETTIMEOUT) { + //TODO SERVLET3 - async } } Modified: tomcat/trunk/java/org/apache/coyote/http11/Http11Processor.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/Http11Processor.java?rev=794122&r1=794121&r2=794122&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/Http11Processor.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/Http11Processor.java Wed Jul 15 00:33:14 2009 @@ -1106,6 +1106,12 @@ InternalInputBuffer internalBuffer = (InternalInputBuffer) request.getInputBuffer(); internalBuffer.addActiveFilter(savedBody); + } else if (actionCode == ActionCode.ACTION_ASYNC_START) { + //TODO SERVLET3 - async + } else if (actionCode == ActionCode.ACTION_ASYNC_COMPLETE) { + //TODO SERVLET3 - async + } else if (actionCode == ActionCode.ACTION_ASYNC_SETTIMEOUT) { + //TODO SERVLET3 - async } } --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org