On Jul 5, 2010, at 12:45 AM, Leo Romanoff wrote:
>
> Hi guys,
>
> I know that my question is most likely beyond the scope of this mailing
> list, but let me try ;-)
Not really: as you noted below, many GF people are on the list.
I am responsible for the ORB in GF, which implements RMI-IIOP.
>
> I've been using Glassfish together with Grizzly, Atmosphere, JAX-WS, etc.
> Most of these technologies support at least some form of server-side
> asynchronous request processing. And this is very important for development
> of scalable server-side applications.
>
> For my current project, I'd like to use RMI for communication between
> clients and servers. BTW, servers are standalone Java applications (using
> embedded GF, Grizzly, Jetty and many other things), as they need explicit
> control over multi-threading which is prohibited by some JavaEE specs like
> EJB, etc. And I of course know that RMI is a synchronous invocation, as it
> was envisioned. But I'd like to benefit from asynchronous
> non-thread-blocking request processing approach if possible and I'd like to
> do it in a transparent way for a client (i.e. it should look like a usual
> local/library call). I think, it should be possible in principle, even
> though I couldn't find anything like this yet. After all, there is a socket
> listening to requests and then triggering server-side stubs. If requests
> could be intercepted at this point, then suspended, and the task for their
> processing could be put on the thread pool or something similar, then after
> their processing is over and response is prepared, requests could wake up
> and response could be sent. But it is not clear for me, if such hooks are
> exposed by the JDK and if it is possible at all.
Have you looked at asynchronous EJBs in the EJB 3.1 specification?
This does pretty much everything that you want, including the ease of use
you get because any serializable Java object can be an argument or result
of an EJB call (unlike the XML-based remoting mechanisms, which are more
limited in their serialization capabilities). I think the current implementation in
GF spins a invocation thread to block waiting for the reply, while the client thread
continues on.
>
> BTW, the reason for going for RMI and not JMS, REST or WS, is that clients
> are created by 3rd parties, not by me, and I cannot force them to follow a
> certain design pattern. Plus I need a very good scalability, I need to serve
> e.g. 10000 requests simultaneously. With JMS, clients would need to write
> their apps using an explicitlty asynchronous design pattern and they are
> restricted to Java. For WS, clients may do invocations almost transparently,
> but overhead introduced by JAX-WS and XML parsing is pretty big. REST is
> almost the same. Therefore I thought that asynchronous RMI could be the best
> solutuion, if such thing would exist, of course. But may be I also
> overcomplicate things? May be there are much simpler scalable and (almost)
> client-transparent solutions?
>
> What do you think about the idea? Have you ever heard about such a thing?
Yes, we have discussed it >10 years ago at the OMG in the RMI-IIOP spec days,
but there was insufficient interest to get anything done at the time.
> 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? 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.
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. I need to think about that part further. 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.
As far as async RMI-JRMP (the JDK version of RMI that is not IIOP based), I don't
know anything about that. RMI-JRMP is not supported in GF: we use RMI-IIOP
instead. There probably are ways to do similar things in RMI-JRMP, but I can't
help with that.
Ken.