Uploaded image for project: 'ActiveMQ Classic'
  1. ActiveMQ Classic
  2. AMQ-3447

When MessageListenerServlet is running under servlet3, the continuation is not timing out.

Attach filesAttach ScreenshotVotersWatch issueWatchersCreate sub-taskLinkCloneUpdate Comment AuthorReplace String in CommentUpdate Comment VisibilityDelete Comments
    XMLWordPrintableJSON

Details

    • Bug
    • Status: Resolved
    • Major
    • Resolution: Fixed
    • 5.5.0
    • 5.9.0
    • None
    • Ubuntu 11.04 using glassfish as web container running servlet 3.0 webapp.

    Description

      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.

      Attachments

        Activity

          This comment will be Viewable by All Users Viewable by All Users
          Cancel

          People

            Unassigned Unassigned
            jackygurui Rui Gu
            Votes:
            1 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Slack

                Issue deployment