dev@jsr311.java.net

RE: Re: Asynchronous REST service

From: Larry Cable <lcable_at_bea.com>
Date: Fri, 18 May 2007 10:55:21 -0700

I know it's a little premature to be suggesting that this may be a requirement or a constraint however I anticipate
that the forthcoming Servlet.next JSR will attempt to solve the asynchronous/long running response problem I would
like to think that we could ensure that whatever we come up with here that would integrate well within such a
Servlet container.
 
- Larry

________________________________

From: Marc Hadley [mailto:Marc.Hadley_at_Sun.COM]
Sent: Fri 5/18/2007 8:09 AM
To: dev_at_jsr311.dev.java.net
Subject: Re: Asynchronous REST service



On May 16, 2007, at 3:29 AM, Hao He wrote:
>
> Thanks for the response. Yes, it is very neat and I like it.
>
> What if:
>
> @HttpMethod("POST")
> public process(Source xmlDoc, Response resp) {
> int processId = enqueueRequest(xmlDoc);
> URI processUri = getProcessUri(processId);
> Response.Builder.seeOther(processUri).header("Retry-After",
> 120).build(resp);
> resp.close();
> /* continue to do other processing */
> }
>
> ?
>
> In this way, we don't need to use a queue or start a new thread but
> doing the processing in the same method.
>
I think there are two reasons you might want to adopt an asynchronous
pattern:

- The processing is likely to take a long time
- The processing requires access to a shared resource (in the general
sense of the word) that doesn't support concurrent access very well

In both cases you probably don't want multiple request threads doing
the work since that is likely to negatively impact performance of
the web tier (since the request handling threads are tied up). For
this reason I think a queue-based approach with a separate thread (or
pool) to handle queued tasks would be a better solution.

Marc.

> -----Original Message-----
> From: Marc Hadley [mailto:Marc.Hadley_at_Sun.COM]
> Sent: Wed 16/05/2007 10:56
> To: dev_at_jsr311.dev.java.net
> Subject: Re: Asynchronous REST service
>
> I think you could do most of what you suggest just using HTTP and
> without inventing a receipt document. E.g. the response to the
> request that starts the async processing could use the 303 status and
> include a Location and Retry-After header. The client can then pick
> up the results or an error response from the URI provided after the
> time specified by the server has passed.
>
> Initial request:
>
> POST /processor HTTP/1.1
> Host: example.com
> Content-Type: application/xml
> Content-Length: nnnn
>
> ...
>
> Response:
>
> HTTP/1.1 303 See Other
> Location: http://example.com/processor/1234567890
> Retry-After: 120
> Content-Length: 0
>
> Susequent request to retrieve response:
>
> GET /processor/1234567890 HTTP/1.1
> Host: example.com
>
> Response:
>
> HTTP/1.1 200 OK
> Content-Type: application/xml
> Content-Length: nnnn
>
> ...
>
> Exactly how the back-end processing occurs doesn't concern us but I'd
> think it would involve posting the request to a message queue or
> something like that. You could implement the above with something like
>
> @UriTemplate("/processor")
> @ConsumeMime("application/xml")
> @ProduceMime("application/xml")
> public class Processor {
>
> @HttpMethod("POST")
> public Response process(Source xmlDoc) {
> int processId = enqueueRequest(xmlDoc);
> URI processUri = getProcessUri(processId);
> return Response.Builder.seeOther(processUri).header("Retry-
> After",120).build();
> }
>
> @HttpMethod
> @UriTemplate("{id}")
> public Response getResult(@UriParam("id") int id) {
> Result r = findResult(id);
> if (Result.completed()) {
> return Response.Builder.ok(r);
> } else {
> URI processUri = getProcessUri(id);
> return Response.Builder.seeOther(processUri).header("Retry-
> After",120).build();
> }
> }
>
> ...
> }
>
> Marc.
>
> On May 15, 2007, at 8:00 PM, Hao He wrote:
>
> >
> > Hi,
> >
> > One of a very patterns we found is what we call "Asynchronous REST
> > service" [1].
> >
> > "An asynchronous service needs to perform the following:
> >
> > 1. Return a receipt immediately upon receiving a request.
> > 2. Validate the request.
> > 3. If the request if valid, the service must act on the request
> > as soon as possible. It must report an error if the service cannot
> > process the request after a period of time defined in the service
> > contract.
> >
> > Request Receipt
> >
> > An example receipt is shown below:
> >
> > <receipt xmlns="http://www.xml.org/2004/rest/receipt" requestUri =
> > "http://www.example.com/xya343343" received = "2004-10-03T12:34:33
> > +10:00">
> > <transaction uri="http://www.example.com/xyz2343" status =
> > "http://www.example.com/xyz2343?view=status"/>
> > </receipt>
> >
> > A receipt is a confirmation that the server has received a request
> > from a client and promises to act on the request as soon as
> > possible. The receipt element should include a received attribute,
> > the value of which is the time the server received the request in
> > WXS dateTime type format. The requestUri attribute is optional. A
> > service may optionally create a request resource identified by the
> > requestUri. The request resource has a representation, which is
> > equivalent to the request content the server receives. A client may
> > use this URI to inspect the actual request content as received by
> > the server. Both client and server may use this URI for future
> > reference. "
> >
> > So, how does this case go with the current REST API?
> >
> > 1. http://www.xml.com/pub/a/2004/08/11/rest.html?page=2
> >
> > Hao
> >
>
> ---
> Marc Hadley <marc.hadley at sun.com>
> CTO Office, Sun Microsystems.
>
>
>
>

---
Marc Hadley <marc.hadley at sun.com>
CTO Office, Sun Microsystems.
Notice:  This email message, together with any attachments, may contain information  of  BEA Systems,  Inc.,  its subsidiaries  and  affiliated entities,  that may be confidential,  proprietary,  copyrighted  and/or legally privileged, and is intended solely for the use of the individual or entity named in this message. If you are not the intended recipient, and have received this message in error, please immediately return this by email and then delete it.