From: Greg W. <gr...@mo...> - 2005-12-20 11:32:46
|
Robert, OK I understand now. I'll look in the next few days how this can be supported - suspending even when the response has been committed. But as for your proposed use of it - I would not recommend it as it is basically a streaming response. While streaming responses do work for the majority of clients, they do cause many proxies a bit of trouble and they break server statistics and generally are a difficult fit with HTTP. Even some browsers have difficulty with streaming and you can often get poor feedback to users ( hourglass symbols or other transfer in progress indications). The cost of an new request from the client is small - just my 2c But I will work to supporting this approach. cheers Robert Kieffer wrote: > [Greg, sorry for the delay in reposting this to the list - It took a > couple tries to actually get on the jetty listserv. Something about not > having a "postmaster" address :-\ ] > > So... first, thanks for the response. However, I think we may be > talking about slightly different things here. I was not asking for the > ablility to return multiple responses. Rather, I'd like to return the > same response in multiple chunks. This way the client need not issue > multiple requests (which may be expensive to set up/handle on the > server). Instead, it issues a single request, which the server keeps > open for as long as communication with the client is necessary. This is > the approach we took on AIMExpress and it works quite well. Essentially > the control flow from the server looks like ... > > - receive request > - return response headers that configure caching, transfer-encoding > (chunked), etc. > - suspend (until some external event occurs) > - resume the response to send a chunk of data back > - suspend (until next external event) > - resume the response again, send another chunk of data back > - suspend > - etc ... > - eventually "finish" the response once the server no longer needs to > talk to the client. > > Please note that I'm pretty sure this is doeable since I have it working > in the latest version of Jetty. I simply made the following changes: > - When suspend()'ing the RetryContinuation, if the suspend fails I > create a new RetryContinuation. This involved adding a > Request.setContinuation() method so I could null out the requests' > continuation, then I simply getContinuation(true) again to create the > new one... and suspend() that. > - I've commented out the _timeoutTask scheduling since this was causing > the response to be finished prematurely. > > With these changes, I'm able to suspend-resume a response an indefinite > number of times, trickling back data each time. However it's very > "hacked" into the system right now - I'm probably breaking the > bejezeezus out of something... I just don't know what. I was hoping > there would be a more formal/efficient method that didn't involve > creating a continuation each time. > > Thoughts? > > - rwk > > > > Greg Wilkins wrote: > >> There can only be one response that actually goes to the client. Once >> that >> response has gone, another requests must be received from the client >> before >> you can suspend/resume on the continuation. It will probably be the >> same continuation object. >> >> So normally with a continuation you will the events like: >> >> request >> suspend >> resume >> retry request >> response. >> >> >> You could suspend several times: >> >> >> request >> suspend >> resume >> retry request >> suspend >> resume >> retry request >> suspend >> resume >> retry request >> response. >> >> >> but once the response is sent - that's the end of the cycle. >> >> cheers >> >> >> >> Robert Kieffer wrote: >> >>> Hi Greg, >>> >>> I've started looking into Jetty Continuations and I've stumbled >>> across something I wasn't expecting - it appears a continuation can >>> only be suspended once. Is that correct? >>> >>> I can't decide if this is a bug, a feature, or what. In testing, I >>> have a simple servlet that I was hoping would just spit out a little >>> bit of HTML every 2 seconds indefinitely (see code below). However, >>> the doGet method is only invoked twice - a result of the initial >>> invocation, and then the again after I call Continuation.suspend() >>> the first time. Subsequent calls to suspend() don't appear to work. >>> >>> Are continuations designed this way? Is there a way to repeatedly >>> suspend a response? >>> >>> Cheers, >>> >>> - rwk >>> >>> ------------------------------------------------------------------------ >>> >>> public void doGet(HttpServletRequest request, HttpServletResponse >>> response) throws ServletException, IOException >>> { long TIMEOUT = 2000L; >>> StringWriter sout = new StringWriter(); >>> PrintWriter out = new PrintWriter(sout); >>> >>> // Render html >>> out.println("<h1>Hello WOILD! *whew*</h1>"); >>> out.println("<p><script>document.write(new >>> Date()*1)</script><p>"); >>> >>> // Flush obuf >>> byte[] obuf = sout.toString().getBytes("UTF-8"); >>> response.getOutputStream().write(obuf); >>> response.flushBuffer(); >>> >>> // Set up continuation >>> Request r = (Request)request; >>> Continuation c = r.getContinuation(true); >>> c.suspend(TIMEOUT); >>> } >> >> |