Read the javadocs for Connection.setExceptionListener()
and it is also required such that the server can detect a vanished/crashed client.
The requirement is for any unrecoverable communication problem.
Like in CORBA,
Completed No - can be tried by attempting reconnection
Completed Maybe - is a problem that needs reporting to the user
The server may disallow reconnection if the "grace" period has expired.
i.e. it has decided the client has crashed.
We discussed this on a JMS thread didn't we?
I think this is a requirement that Adrian brought up a while back. Just now getting to it.
In the context of the remoting code, this only makes sense for oneway calls (async) where the calling thread returns before making the server call:
public void invokeOneway(final Object param, final Map sendPayload, boolean clientSide) throws Throwable
where clientSide is true. Is this what you are wanting; when this call fails, notify an registered exception listener?
It is a common misconception that JMS should use a "One way" invocation.
I've seen this nonsense repeated so many times.
It can use it to optimize certain parts of the protocol, e.g. message delivery
to client only needs to be one-way since the result (both the delivery and whether it
was processed successfully) is communicated back through acknowledgements.
It is JMS that implements the "One Way" behaviour, it has other requirements to satisfy
beyond the transport (like persistence and transactions).
When a client does
in a persistent context, the client needs to know that when that method
returns the message delivery is guaranteed.
It cannot do this if the transport is "One Way" (i.e. best effort, maybe it will get there
and you don't know the result).
What JMS wants is the following (client side description):
1) Make a bi-directional connection (could be two separate uni-directional connections that are linked in terms of state or uni-directional with polling).
2) Let the server push messages to the client back along that connection
3) If that connection fails due to unrecoverable transport failures
connection.setExceptionListener() is invoked with the failure exception.
Of course, I don't expect you to invoke the jms api directly, that mapping will
be provided by the JMS code from the remoting api.
Ok. I get what you want for JMS. So what do you want from remoting that is not already there?
Here are the possible ways to use remoting:
1. make a uni-directional, synchronous call from client to server, which will throw a CanNotConnectException if the transport can not connect to the server.
2. make a uni-directional, asynchronous call from client to server, where the client's calling thread will block until the server call is made. This will throw a CanNotConnectException if the transport can not connect to the server.
3. make a uni-directional, asynchronous call from the client to the server, where the client's calling thread will NOT block until the server call is made, but return immediately. Another work thread on the client will then make the call to the server. In this case, the client will NOT BE AWARE OF ANY TRANSPORT FAILURES. This is the case I mentioned previously where I can add an API for registering a exception listener.
4. The server has a handle to the client's callback listener and will make calls on it for callbacks. In this case, the server (invocation handler) will get a HandleCallbackException if can not deliver the callback to the client's listener.
Other than number 3, I don't see where you would not have what you need.
The other thing, which is on my roadmap but have not started, is a true bi-directional transport like UIL2.
What is missing is that the transport could fail while there are no calls.
1) I register a message listener but there are no messages.
2) The server or network fails
3) JMS needs to invoke the ExceptionListener to tell the user code about the failure
otherwise onMessage will just wait forever.
Currently, JBossMQ does this by passing a regular ping/pong around the connection.
You have the same issue on the server where the client/network has failed
but you don't know about it, it just looks like the client isn't doing anything.
The server does not want to maintain resources
(unacknowledged messages/temporary destinations/nondurable subscriptions)
for these clients.
Currently UIL2 does this by setting an SOTimeout on the server side
to detect when it stop receiving the pings.
Initial implementation added for this (see http://wiki.jboss.org/wiki/Wiki.jsp?page=Remoting_exception_listener). This is more of a functioning placeholder for one that will be pluggable in regards to how it detects the connection failure.