Author: fhanik
Date: Sat Apr 5 13:44:42 2008
New Revision: 645175
URL: http://svn.apache.org/viewvc?rev=645175&view=rev
Log:
Implement asynchronous callbacks for CometEvent.close and CometEvent.setTimeout
to avoid connections with very long timeouts getting stuck
CometProcessor implements servlet interface, or the code will fail deployment
if no keepalive, close the connection after comet transaction is complete
Modified:
tomcat/trunk/java/org/apache/catalina/CometProcessor.java
tomcat/trunk/java/org/apache/catalina/connector/CometEventImpl.java
tomcat/trunk/java/org/apache/catalina/connector/Request.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/tomcat/util/net/NioEndpoint.java
Modified: tomcat/trunk/java/org/apache/catalina/CometProcessor.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/CometProcessor.java?rev=645175&r1=645174&r2=645175&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/CometProcessor.java (original)
+++ tomcat/trunk/java/org/apache/catalina/CometProcessor.java Sat Apr 5
13:44:42 2008
@@ -21,6 +21,7 @@
import java.io.IOException;
import javax.servlet.ServletException;
+import javax.servlet.Servlet;
/**
* This interface should be implemented by servlets which would like to handle
@@ -29,7 +30,7 @@
* Note: When this interface is implemented, the service method of the servlet
will
* never be called, and will be replaced with a begin event.
*/
-public interface CometProcessor {
+public interface CometProcessor extends Servlet{
/**
* Process the given Comet event.
Modified: tomcat/trunk/java/org/apache/catalina/connector/CometEventImpl.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/connector/CometEventImpl.java?rev=645175&r1=645174&r2=645175&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/connector/CometEventImpl.java
(original)
+++ tomcat/trunk/java/org/apache/catalina/connector/CometEventImpl.java Sat Apr
5 13:44:42 2008
@@ -26,6 +26,7 @@
import org.apache.catalina.CometEvent;
import org.apache.catalina.util.StringManager;
+import org.apache.coyote.ActionCode;
public class CometEventImpl implements CometEvent {
@@ -92,8 +93,10 @@
if (request == null) {
throw new
IllegalStateException(sm.getString("cometEvent.nullRequest"));
}
+ boolean iscomet = request.isComet();
request.setComet(false);
response.finishResponse();
+ if (iscomet) request.cometClose();
}
public EventSubType getEventSubType() {
@@ -116,6 +119,7 @@
UnsupportedOperationException {
if (request.getAttribute("org.apache.tomcat.comet.timeout.support") ==
Boolean.TRUE) {
request.setAttribute("org.apache.tomcat.comet.timeout", new
Integer(timeout));
+ if (request.isComet()) request.setCometTimeout((long)timeout);
} else {
throw new UnsupportedOperationException();
}
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=645175&r1=645174&r2=645175&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/connector/Request.java (original)
+++ tomcat/trunk/java/org/apache/catalina/connector/Request.java Sat Apr 5
13:44:42 2008
@@ -2256,6 +2256,13 @@
return (inputBuffer.available() > 0);
}
+ public void cometClose() {
+ coyoteRequest.action(ActionCode.ACTION_COMET_CLOSE,getEvent());
+ }
+
+ public void setCometTimeout(long timeout) {
+ coyoteRequest.action(ActionCode.ACTION_COMET_SETTIMEOUT,new
Long(timeout));
+ }
// ------------------------------------------------------ Protected Methods
Modified: tomcat/trunk/java/org/apache/coyote/ActionCode.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/ActionCode.java?rev=645175&r1=645174&r2=645175&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/ActionCode.java (original)
+++ tomcat/trunk/java/org/apache/coyote/ActionCode.java Sat Apr 5 13:44:42 2008
@@ -141,7 +141,7 @@
/**
- * Callback for begin Comet processing
+ * Callback for end Comet processing
*/
public static final ActionCode ACTION_COMET_END = new ActionCode(22);
@@ -151,7 +151,16 @@
*/
public static final ActionCode ACTION_AVAILABLE = new ActionCode(23);
+ /**
+ * Callback for an asynchronous close of the Comet event
+ */
+ public static final ActionCode ACTION_COMET_CLOSE = new ActionCode(24);
+ /**
+ * Callback for setting the timeout asynchronously
+ */
+ public static final ActionCode ACTION_COMET_SETTIMEOUT = new
ActionCode(25);
+
// ----------------------------------------------------------- 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=645175&r1=645174&r2=645175&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java
(original)
+++ tomcat/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java Sat Apr
5 13:44:42 2008
@@ -1205,6 +1205,10 @@
comet = true;
} else if (actionCode == ActionCode.ACTION_COMET_END) {
comet = false;
+ } else if (actionCode == ActionCode.ACTION_COMET_CLOSE) {
+ //no op
+ } else if (actionCode == ActionCode.ACTION_COMET_SETTIMEOUT) {
+ //no op
}
}
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=645175&r1=645174&r2=645175&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java
(original)
+++ tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java Sat Apr
5 13:44:42 2008
@@ -777,7 +777,8 @@
return SocketState.CLOSED;
} else if (!comet) {
recycle();
- return SocketState.OPEN;
+ //pay attention to the keep alive flag set in process()
+ return (keepAlive)?SocketState.OPEN:SocketState.CLOSED;
} else {
return SocketState.LONG;
}
@@ -1219,6 +1220,21 @@
comet = true;
} else if (actionCode == ActionCode.ACTION_COMET_END) {
comet = false;
+ } else if (actionCode == ActionCode.ACTION_COMET_CLOSE) {
+ NioEndpoint.KeyAttachment attach =
(NioEndpoint.KeyAttachment)socket.getAttachment(false);
+ attach.setCometOps(NioEndpoint.OP_CALLBACK);
+ //notify poller if not on a tomcat thread
+ RequestInfo rp = request.getRequestProcessor();
+ if ( rp.getStage() != org.apache.coyote.Constants.STAGE_SERVICE )
//async handling
+ socket.getPoller().cometInterest(socket);
+ } else if (actionCode == ActionCode.ACTION_COMET_SETTIMEOUT) {
+ if (param==null) return;
+ NioEndpoint.KeyAttachment attach =
(NioEndpoint.KeyAttachment)socket.getAttachment(false);
+ long timeout = ((Long)param).longValue();
+ //if we are not piggy backing on a worker thread, set the timeout
+ RequestInfo rp = request.getRequestProcessor();
+ if ( rp.getStage() != org.apache.coyote.Constants.STAGE_SERVICE )
//async handling
+ attach.setTimeout(timeout);
}
}
Modified: tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java?rev=645175&r1=645174&r2=645175&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java Sat Apr 5
13:44:42 2008
@@ -1635,6 +1635,7 @@
protected void reg(SelectionKey sk, KeyAttachment attachment, int
intops) {
sk.interestOps(intops);
attachment.interestOps(intops);
+ attachment.setCometOps(intops);
}
protected void timeout(int keyCount, boolean hasEvents) {
@@ -1659,6 +1660,7 @@
} else if ( ka.getError() ) {
cancelledKey(key, SocketStatus.ERROR,true);
} else if (ka.getComet() && ka.getCometNotify() ) {
+ ka.setCometNotify(false);
reg(key,ka,0);//avoid multiple calls, this gets
reregistered after invokation
//if (!processSocket(ka.getChannel(),
SocketStatus.OPEN_CALLBACK)) processSocket(ka.getChannel(),
SocketStatus.DISCONNECT);
if (!processSocket(ka.getChannel(),
SocketStatus.OPEN)) processSocket(ka.getChannel(), SocketStatus.DISCONNECT);
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]