Messaging clients should be able to send data on the wire without the unnecessarily added burden of waiting for a reply. Similarly, the server should be able to asynchronously send data to the client.
Tom Elrod wrote:
Have made the code changes (for jira issue http://jira.jboss.com/jira/browse/JBREM-548 ) so that if doing one-way invocations, only the request ever gets written to the wire and that thread on the client returns immediately after the write. On the server side, it never writes the response back to client.
In what release is this available? I would like to play a little bit with it.
Tom Elrod wrote:
Probably good to have better definition of what asynchronous means. At a high level in the call stack, can just mean using a future model to make call and wait for a response to come back at later point in time (or just a callback on a different thread at later point in time). At lowest level, could be talking about only writing on the wire and not waiting for response off the wire. Lots of places term can be used in between the high and low level.
In what I am concerned, asynchronous means the ability of using a client thread to put data on the wire and return immediately without waiting for any reply. "True" asynchronicity in this context means that no unnecessary work is done (like sending a reply but discarding it on the client side).
Here is a an example that came up in the forums the other day (there is also a support case related to this from another customer with JBossMQ which suffers from a similar problem):
The customer has a fantastic high bandwidth network, but it has very high latency (large round trip time). They would love to use their network to it's capacity with our messaging product. Currently when we deliver messages (usually one by one) from the server to the client consumer they are delivered by a remoting RPC call. This writes to a socket then waits for a response. Therefore the minimum amount of time to send one message is 2 x latency. And this is for every message (!).
The "correct" way to do this is to forget responses, just write to the socket and carry on. Flow control messages from the client to the server then prevent the client being overrun with messages (this is kind of analogous to how TCP flow control works - although there are some differences).
Your "correct" approach raises the following issue:
Assume that you want to write a client that needs guaranteed delivery on a queue. You write that client to create a persistent message and send the message by invoking a producer's send() method. As soon as your send() method returns without an exception, this is a hard guarantee to your client that the messaging broker accepted the message for further delivery. You cannot have that guarantee without you call actually reaching the server. At that point, the client can call System.exit() and go to the client's heaven, fully assured that his message is being taken care of. If you use the asynchronous approach you describe, the client will be never able to rely on this guarantee.
Moving on to serialization. JBoss Remoting is based around the idea of invocations that get serialized. We a) don't want invocations and b) In almost every case we don't want serialization either (there is one case we do want serialization) - this is because we know the types of the objects being transmitted at compile time so we can encode that information in a much more efficient way (in a byte) - the overhead of serialization is just to much for us.
I disagree with a). An RPC model is very convenient when dealing with life cycle operations such as creating connections, sessions, producer, consumer, browsers, etc. It's a very convenient model for a high granularity reliable operations.
The alternative would be to send an asynchronous invocation to say, create a Session, and then block on the client for an explicit acknowledgment from the server. Why would you want to do that when you have RPC for free?
I agree with b), though. This is an overhead we can do without.