package com.mcvw; import java.util.Date; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.core.Response; import org.jboss.resteasy.annotations.Suspend; import org.jboss.resteasy.spi.AsynchronousResponse; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Controller; @Path("/") @Controller public class AsyncController { private static final Logger _logger = LoggerFactory.getLogger(AsyncController.class); private static final int SERVLET_TIMEOUT = 30000; private ExecutorService _executor = Executors.newSingleThreadExecutor(); private int counter = 0; AsyncController() { System.out.println("console, in ctor()"); _logger.error("logger, in ctor()"); } @GET public String index() { _logger.error("hello from index"); return "hello from index"; } @GET @Path("/timeout200") public void timeoutGets200(@Suspend(SERVLET_TIMEOUT) final AsynchronousResponse response) { _logger.debug("returning nothing, forcing a timeout"); } @GET @Path("/timeoutStacks") public void timeoutStacksMultipleResponses(@Suspend(SERVLET_TIMEOUT) final AsynchronousResponse response) throws InterruptedException { Runnable runner = new Runnable() { public void run() { // force timeout every other call if (counter++ % 2 == 0) { try { int sleeper = SERVLET_TIMEOUT + 10000; _logger.debug("forcing timeout by sleeping for " + sleeper + "ms"); Thread.sleep(sleeper); } catch (InterruptedException e) { } } try { Date date = new Date(); _logger.debug("writing response"); response.setResponse(Response.ok("string returned at " + date + "\n").build()); } catch (Exception e) { _logger.debug("failed setting response", e); } } }; _executor.submit(runner); } }