Async support draft

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Async support draft

VANKEISBELCK Remi
Hi folks,

I've played a bit with Async Support. 

I want to be able to use Servlet3's AsyncContext feature in order to write non-blocking style Stripes actions.

My use case is asynchronous, non-blocking invocation of a remote Web Service in an Action Bean's event handler, which gets the webservice response and forwards to some view :

1/ the handler is invoked
2/ it uses an async http client in order to contact a web service, passing it a callback
3/ callback is called when the web service returns
4/ action bean does some processing of the WS response
5/ view (JSP) is rendered

This is not possible with Stripes out of the box : the lifecycle is implemented over the thread-per-request, synchronous model. 

So I wondered how we could implement this, in a simple and non-disruptive manner. 

The simplest solution I found was to introduce a new Resolution abstract subclass, called AsyncResolution. This one would get passed the AsyncContext, and would do whatever it needs with it, with the responsibility of completing or dispatching.

You can then write an asynchronous handler like this :

public Resolution myAsync() {
  return new AsyncResolution() {
    ...
  }
}

A full example that performs a request on the GitHub API :
(It's a very verbose example of course but shows how it's done)

The AsyncResolution is a Resolution and has an "execute(request,response)" method. But it also has a reference to the AsyncContext that Stripes has started for us : the dispatcher now checks whether the Resolution is async or not, and starts async processing if needed, passing the AsyncContext to the resolution. 

Therefore, the resolution can access the AsyncContext in its execute(req,resp) method, and call asyncContext.complete() or dispatch().

I had to change the lifecycle a little bit to make this work, and also to cleanup some ThreadLocals that were never removed. The thread is basically "lost" as soon as you call request.startAsync(), so the ExecutionContext thread local leaked.

Also, this approach doesn't allow for async TypeConverters, Interceptors etc. : we'd need to rewrite the whole lifecycle in order to make this work. But I don't know if it's a mandatory requirement. The main requirement for me is that I can leverage the non-blocking model when calling external web services from my controllers. 

What do you guys think ? Are you interested in this feature ? I think it's a must have today, but maybe it's just me...

I have commited my code in a "remi_async" branch, if you want to try it out. There's also an async action example, along with the other samples, the one that fetches commits from gh asynchronously.

Cheers

Rémi









------------------------------------------------------------------------------

_______________________________________________
Stripes-development mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/stripes-development
Reply | Threaded
Open this post in threaded view
|

Re: Async support draft

Timothy Stone-6
On 8/21/15 8:15 AM, VANKEISBELCK Remi wrote:
> Hi folks,
>
> I've played a bit with Async Support.
>
> I want to be able to use Servlet3's AsyncContext feature in order to
> write non-blocking style Stripes actions.
>

...snip... awesome preview of feature ...

>
> What do you guys think ? Are you interested in this feature ? I think
> it's a must have today, but maybe it's just me...

YES.

>
> I have commited my code in a "remi_async" branch, if you want to try it
> out. There's also an async action example, along with the other samples,
> the one that fetches commits from gh asynchronously.





------------------------------------------------------------------------------
_______________________________________________
Stripes-development mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/stripes-development