[
https://issues.apache.org/jira/browse/AMQ-3447?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13682371#comment-13682371
]
Thomas Themel commented on AMQ-3447:
------------------------------------
This looks like it's actually a bug in Jetty's continuation support, but in the
mean time, here's a workaround:
--- MessageListenerServlet.java.orig 2013-02-06 15:13:06.000000000 +0100
+++ MessageListenerServlet.java 2013-06-13 17:17:43.562011800 +0200
@@ -41,6 +41,7 @@
import org.apache.activemq.MessageAvailableConsumer;
import org.eclipse.jetty.continuation.Continuation;
+import org.eclipse.jetty.continuation.ContinuationListener;
import org.eclipse.jetty.continuation.ContinuationSupport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -307,13 +308,29 @@
if (message == null &&
client.getListener().getUndeliveredMessages().size() == 0) {
Continuation continuation =
ContinuationSupport.getContinuation(request);
+
+ // Add a listener to the continuation to make sure it actually
+ // will expire (seems like a bug in Jetty Servlet 3
continuations, see https://issues.apache.org/jira/browse/AMQ-3447
+ continuation.addContinuationListener(new ContinuationListener()
{
+ @Override public void onTimeout(Continuation cont) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Continuation " +
cont.toString() + " expired.");
+ }
+ }
+ @Override public void onComplete(Continuation cont) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Continuation " +
cont.toString() + " completed.");
+ }
+ }
+ });
+
if (continuation.isExpired()) {
response.setStatus(HttpServletResponse.SC_OK);
StringWriter swriter = new StringWriter();
PrintWriter writer = new PrintWriter(swriter);
> When MessageListenerServlet is running under servlet3, the continuation is
> not timing out.
> ------------------------------------------------------------------------------------------
>
> Key: AMQ-3447
> URL: https://issues.apache.org/jira/browse/AMQ-3447
> Project: ActiveMQ
> Issue Type: Bug
> Affects Versions: 5.5.0
> Environment: Ubuntu 11.04 using glassfish as web container running
> servlet 3.0 webapp.
> Reporter: Rui Gu
> Labels: Ajax
>
> In MessageListenerServlet.java
> if (message == null &&
> client.getListener().getUndeliveredMessages().size() == 0) {
> Continuation continuation =
> ContinuationSupport.getContinuation(request);
>
> if (continuation.isExpired()) {
> response.setStatus(HttpServletResponse.SC_OK);
> StringWriter swriter = new StringWriter();
> PrintWriter writer = new PrintWriter(swriter);
> writer.println("<ajax-response>");
> writer.print("</ajax-response>");
> writer.flush();
> String m = swriter.toString();
> response.getWriter().println(m);
>
> return;
> }
> continuation.setTimeout(timeout);
> continuation.suspend();
> LOG.debug( "Suspending continuation " + continuation );
>
> // Fetch the listeners
> AjaxListener listener = client.getListener();
> listener.access();
> // register this continuation with our listener.
> listener.setContinuation(continuation);
>
> return;
> }
> Based on above code, the continuation is expected to be expired after given
> timeout when there is no message available for the ajax client and the ajax
> client will then receive an "empty" message. However based on the servlet 3
> Continuation implementation in jetty (Servlet3Continuation.java) the only
> place where the continuation is set to expire is within the below method
> (there is a bug in this method as well).
> public void addContinuationListener(final ContinuationListener listener)
> {
> AsyncListener wrapped = new AsyncListener()
> {
> public void onComplete(final AsyncEvent event) throws IOException
> {
> listener.onComplete(Servlet3Continuation.this);
> }
> public void onError(AsyncEvent event) throws IOException
> {
> listener.onComplete(Servlet3Continuation.this);
> }
> public void onStartAsync(AsyncEvent event) throws IOException
> {
> event.getAsyncContext().addListener(this);
> }
> public void onTimeout(AsyncEvent event) throws IOException
> {
> _expired=true;
> listener.onTimeout(Servlet3Continuation.this);
> }
> };
>
> if (_context==null)
> _context.addListener(wrapped);
> else
> _listeners.add(wrapped);
> }
> Without adding a listener the continuation will never be set to expire,
> therefore the "empty" response is never sent back to the client, the
> connection from the client is resumed and suspended over and over again until
> the connection is aborted by client or there is a message available.
--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira