Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 352517 - no server-side way to trigger resume of suspended continuation: calling continuation.resume() in onTimeout() handler no longer resumes continuation
Summary: no server-side way to trigger resume of suspended continuation: calling conti...
Status: RESOLVED WORKSFORME
Alias: None
Product: Jetty
Classification: RT
Component: server (show other bugs)
Version: unspecified   Edit
Hardware: All All
: P3 normal (vote)
Target Milestone: 7.5.x   Edit
Assignee: Greg Wilkins CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-07-19 20:47 EDT by Tim Williamson CLA
Modified: 2011-09-06 00:41 EDT (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Tim Williamson CLA 2011-07-19 20:47:04 EDT
Build Identifier: 

I have a servlet where the client keeps a long-lived connection open, and the server periodically sends an update.
With Jetty 8.0.0 M1, code like the following:
		if (continuation.isInitial()) {
			continuation.suspend(response);
			continuation.setTimeout(timeout);
			continuation.addContinuationListener(new ContinuationListener()
			{
				@Override
				public void onComplete(Continuation continuation)
				{
					System.out.println("Complete");
				}

				@Override
				public void onTimeout(Continuation continuation)
				{
					try {
						System.out.println("Timeout");
						continuation.resume();
					}
					catch (Exception e) {
						continuation.complete();
					}
				}
			});
		}
		else {
			System.out.println("Resumed");
			continuation.setTimeout(timeout);
			continuation.suspend(response);
		}
worked just fine.  With M3, the "else" clause is never run; the timeout occurs, but connection.resume() does not schedule the connection to be resumed.  As it stands, there appears to be no way in M3 to resume a suspended continuation short of the client sending data, which is not an option in my situation.

I suspect this may be related to https://bugs.eclipse.org/bugs/show_bug.cgi?id=324359

Reproducible: Always

Steps to Reproduce:
See above code snippet.
Comment 1 Greg Wilkins CLA 2011-08-29 00:45:18 EDT
There are several things going on here.

firstly you are kind of mixing up two styles here.  The Jetty Continuation API does not need a resume to be called to re-dispatch a timeout - it should happen automatically (it is the Servlet 3.0 variant of the API that needs that to be done).

However, even with that mixup, your else branch should be called.... hmmm unless the resume call is throwing an exception, which you then catch and call complete - which then prevents the redispatch from happening.

Let me just check that is the case....
Comment 2 Tim Williamson CLA 2011-08-29 13:21:15 EDT
Thanks for the info about not needing to call resume().  In 8.0.0M1 it does indeed behave as you expect; the resume() is not needed.

However, in both 8.0.0M3 and 8.0.0RC0, the "else" branch is not executed regardless of whether resume() is called or not.  So whatever got broken after 8.0.0M1 appears to be unrelated to the resume() call.
Comment 3 Greg Wilkins CLA 2011-09-06 00:41:10 EDT
I just tested the code:

public class Test352517
{
    public static void main(String[] args) throws Exception
    {
        Server server = new Server(8080);

        ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
        context.setContextPath("/");
        server.setHandler(context);

        context.addServlet(new ServletHolder(new SuspendServlet()),"/");

        server.start();
        server.join();
    }
    
    static class SuspendServlet extends HttpServlet
    {
    	@Override
    	protected void doGet(HttpServletRequest request, HttpServletResponse response)
    	throws ServletException, IOException 
    	{       
			System.out.println("doGet");
    		Continuation continuation = ContinuationSupport.getContinuation(request);

    		if (continuation.isInitial()) 
    		{
    			continuation.suspend(response);
    			continuation.setTimeout(1000);
    			continuation.addContinuationListener(new ContinuationListener() 
    			{
    				@Override
    				public void onComplete(Continuation continuation)
    				{
    					System.out.println("Complete");
    				}

    				@Override
    				public void onTimeout(Continuation continuation)
    				{
						System.out.println("Timeout");
    				}
    			});
    		}
    		else 
    		{
    			System.out.println("Resumed");
    		}
    	}
    }
}


in 8.0.0 and the output was as expected for a single hit to 

http://localhost:8080
2011-09-06 14:39:23.724:INFO:oejs.Server:jetty-8.0.y.z-SNAPSHOT
2011-09-06 14:39:23.798:INFO:oejs.AbstractConnector:Started SelectChannelConnector@0.0.0.0:8080 STARTING
doGet
Timeout
doGet
Resumed
Complete


Please reopen if you are seeing something different to that.