I. The central change has been to push callbacks back down into the Remoting layer. In
particular, where on HEAD ServerConsumerEndpoint.Deliverer gets the
ServerInvokerCallbackHandler's Client and delivers messages to the client side using
Client.invoke(), on the HTTP branch it calls
ServerInvokerCallbackHandler.handleCallback(). As a result, Messaging can take advantage
of Remoting's variety of callback options. In particular, the relevant choices are:
(a) push callbacks: a Connector (complete with ServerSocket) is created on the client
side, and calling ServerInvokerCallbackHandler.handleCallback() causes an invocation to be
made from server side to client side.
(b) poll callbacks: calling ServerInvokerCallbackHandler.handleCallback() causes the
callback to be stored (possibly on disk) until the client side polls for pending
callbacks. No ServerSocket is created on the client side.
It is my understanding that option (a) is suitable for the socket transport, and option
(b) is suitable for the HTTP transport. Switching between the two is done by the
following code in JMSRemotingConnection.start():
| boolean doPushCallbacks =
"socket".equals(serverLocator.getProtocol());
| if (doPushCallbacks)
| {
| if (log.isTraceEnabled()) log.trace("doing push callbacks");
| HashMap metadata = new HashMap();
| metadata.put(InvokerLocator.DATATYPE, "jms");
| metadata.put(InvokerLocator.SERIALIZATIONTYPE, "jms");
| client.addListener(callbackManager, metadata, null, true);
| }
| else
| {
| if (log.isTraceEnabled()) log.trace("simulating push callbacks");
| HashMap metadata = new HashMap();
| metadata.put(CallbackPoller.CALLBACK_POLL_PERIOD, "100");
| client.addListener(callbackManager, metadata);
| }
|
The implementation of Client.addListener() does the rest.
Changes related to callbacks may be found in the following classes:
org.jboss.jms.client.remoting.CallbackManager
org.jboss.jms.client.remoting.CallbackServerFactory (no longer necessary)
org.jboss.jms.client.remoting.JMSRemotingConnection
org.jboss.jms.server.container.InjectionAspect
org.jboss.jms.server.endpoint.ServerConnecionEndpoint
org.jboss.jms.server.endpoint.ServerConsumerEndpoint
In order to replace invocations with callbacks, a callback acknowledgement facility was
added to Remoting. When ServerConsumerEndpoint.Deliverer sends a callback, it also stores
the callback in a pendingCallbacks HashSet, from which it is removed upon acknowledgement.
ServerConsumerEndpoint.stop() waits for pendingCallbacks to go empty before returning. A
callback is acknowledged in one of two ways:
- In the case of push callbacks, ServerInvokerCallbackHandler.handleCallback() does the
acknowledgement after the callback has been pushed to the client side. At this point, the
callback has been processed by MessageCallbackHandler.
- In the case of polled callbacks, the acknowledgement is initiated from the client side
after the callback has been processed by MessageCallbackHandler.
TODO:
1. A callback ID should be stored in pendingCallbacks instead of the callback itself.
2. Unlike Client.invoke(), ServerInvokerCallbackHandler.handleCallback() does not return a
response, so ServerConsumerEndpoint.Deliverer gets no feedback from the client side about
throttling message flow.
II. The new Messaging specific serialization structure interacts with callbacks to
generate some added complexity in JMSWireFormat. Because of the two forms of callbacks,
there are two delivery modes for callbacks, and each has to be unwound to expose the
ClientDelivery. For example, callback polling delivers an ArrayList of pending callbacks,
and each ClientDelivery in the list has to be processed separately. There's also
another related issue. In pull or poll mode, callbacks are stored on the server, which
might involve writing them to secondary storage. Currently, the application's
designated serialization type determines how the callbacks are transferred to and from
disk, but MessagingObjectInputStream and MessagingObjectOutputStream are derived from the
standard java classes, which can't handle Messaging non-Serializable messages. For
now I've worked around the problem in my local version of Remoting, but the problem
still needs to be resolved. Is there any reason the Messaging can't use JBoss
Serialization?
III. I changed org.jboss.test.messaging.tools.jmx.ServiceContainer and
org.jboss.test.messaging.tools.jmx.ServiceContainerConfiguration so that they can pick up
the remoting transport from a <remoting-transport> element in
tests/etc/container.xml.
IV. Right now the HTTP branch runs with my own private version of Remoting. I've
checked in a copy of jboss-remoting.jar in the lib directory.
V. It's 4am and right now it looks like everything's broken. Great. Well, it WAS
working.
View the original post :
http://www.jboss.com/index.html?module=bb&op=viewtopic&p=3978999#...
Reply to the post :
http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&a...