users@grizzly.java.net

Re: Asynchronous request processing for ... RMI

From: Ken Cavanaugh <kencavanaugh_at_mac.com>
Date: Tue, 06 Jul 2010 00:34:33 -0700

On Jul 5, 2010, at 11:20 AM, Leo Romanoff wrote:
>>
>
> I thought about it. But my impression was that EJB 3.1 makes it look
> asynchronous for the client. It is still synchronous on the server-side and
> blocks the thread. Most likely, serving some 10000 long lasting requests
> this way will not scale, or? Another concern - I need explicit controls
> over processing threads and their management. And EJB spec still prohibits
> it AFAIK.

Yes, I am aware of this problem, but from conversations with Ken Saks,
I don't think it's a spec problem, but rather an implementation limitation
at least at present in the GF EJB 3.1 code. Fixing it requires ORB and EJB
changes, which would be very interesting, given sufficient demand for such
an optimization.

>
>
>>> Would it be possible to implement such a solution on top of Grizzly and
>>> how
>>> much effort it would need?
>
>> Yes, but it's rather a lot of work. Will you ever need transactions,
>> security,
>> failover, or load balancing of requests? What about retry policy
>> management
>> for request failures?
>
> At the moment, I don't care about most of these things. I need a good raw
> performance.
> But later it may become important, of course.
>
> What disappoints me a bit, is the fact that all JSRs impelement these
> features using a totally different way. After all, Atmosphere, Metro JAX-WS
> RI with its tubes and fibers, JAX-WS RI AsyncProvider interfaces, etc all
> use roughly similar pattern to implement server-side asynchrony.
>
> As I looked a bit deeper into the implementation of the JAX-WS RI in Metro,
> let me use this as an example. JAX-WS RI approach is actually rather generic
> and flexible. IMHO, more flexible and well-thought through than RMI
> implentations or RESTful implementations like Atmosphere and the like.

Probably true: I've talked a bit about this with Harold (from the Metro team).

> JAX-WS RI waits for incoming request and then creates a task object out of
> it and puts it into a "tube assembly" which contains of multiple processing
> steps. Each step is eventually handled by a dedicated thread-pool. There are
> parts of the overall pipe responsible for transport handling (e.g. HTTP,
> JMS, in-vm and some other transports are supported and new ones can be
> defined), security, XML serialization, etc. And all that is configurable and
> has APIs for building your our tubes and assemble them. Processing can be
> suspended/resumed after each step using a special API. Level of
> multi-threading is configurable by providing your own ThreadPools or
> Executor objects. Once all required steps of the assembly has processed the
> request and produced the response, it will be eventually send out.
>
> And, BTW, the framework itself is rather protocol agnostic. It uses SOAP by
> default, but AFAIK there is nothing in it that mandates that only SOAP can
> be used. If one would use Java Serialization used by RMI, it should work as
> well, I guess. It would be actually rather interesting, if RMI (IIOP or
> JRMP) would be implemented using the same mechanisms. It would make it much
> more configurable, flexible and extendable, plus increase code reuse inside
> GF/JDK.

The main issues in the RMI-IIOP case stem from CORBA requirements, particularly
in maintaining state for Portable Interceptors and the POA. But I should take some time to look
into this further: it does come up in one guise or another from time to time.

>
> It was just an idea... In reality, there are always tons of differences in
> low level details that can make such things impossible. But what do you
> think about this approach?

I don't know enough about Metro to say anything right now, but I'll explore it at
some point.

>
>> There is a lot of serialization machinery to deal with as well,
>> plus issues like stub generation and managing the request->servant (object
>> that
>> implements the remote object) mapping.
>
>> All of this is already implemented in the GF ORB for RMI-IIOP. At some point,
>> I'd like to in fact move the ORB to use Grizzly 2.x as its transport, but that can't
>> happen before GF 3.2 due to lack of resources.
>
> Very interesting.
>
>> It would certainly be possible to implement async RMI-IIOP directly at the
>> level of
>> the ORB, using syntax similar to that supported by the async EJB feature.
>> A good implementation should avoid blocking threads while waiting for a
>> response
>> (even an internal implementation thread is probably too much in some
>> cases).
>> The basic need here is to modify the dynamic stub generator slightly,
>> introducing a new
>> API for the async case.
>
>> The hard part is modifying the client ORB code to save and restore the
>> per-request state.
>
> Can you elaborate a bit more on this? I'm not so deep into RMI
> implementations (yet ;-) to understand the problem that you describe here.

Actually I was thinking about the client side above, which is interesting, but
the server side is much more important for scalability considerations.
But I'm not sure how to do this: what is your long-running server method doing?
Is it computing something expensive, in which case a thread is required anyway?
Or is it making further remote requests (perhaps expensive database queries?)
Essentially it seems that you want to capture the state of your computation
at the point of suspension (remote communications, IO, etc) so that it can be
restored later. This either requires significant restrictions or a general
continuation implementation. But I'm not sure whether the state saved
by a full continuation implementation is significantly smaller than that
saved in a thread.

>
>> I need to think about that part further.
>
> Looking forward to hear more from you, once you made up your mind!
>
>> Obviously a general
>> continuation mechanism would make this easy, but failing that,
>> the basic state to capture is in several ThreadLocals.
>> Then it't a matter of unwinding the method return code so it can be called
>> directly.
>
> There are some attempts to support general continuations in Java (Maxine JVM
> and some others), but it will take a while before it becomes mainstream.

I've see some of this, but I think they generally require extensive bytecode
transformation across the entire execution path, which may be impractical,

> There is also Javaflow, which could be good enough eventually. BTW, Scala
> has a nice support for continuations out of the box in the recent releases.

Scala is interesting, but re-writing part of the ORB in Scala may not be practical
(though it would be interesting!). I'll need to check on the Scala continuation
support: can it capture a full continuation from Scala code that both is called
by and calls into Java code?

Ken.