You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@activemq.apache.org by "Thomas Themel (JIRA)" <ji...@apache.org> on 2013/06/13 18:05:21 UTC

[jira] [Commented] (AMQ-3447) When MessageListenerServlet is running under servlet3, the continuation is not timing out.

    [ 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