[jboss-dev-forums] [Design of Messaging on JBoss (Messaging/JBoss)] - Re: Incorporating Remoting http transport into Messaging
ron_sigal
do-not-reply at jboss.com
Wed Oct 18 04:27:53 EDT 2006
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#3978999
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=3978999
More information about the jboss-dev-forums
mailing list