I have found a problem with ordered message delivery using binding.jms in Tuscany 1.x. The JMS spec says
"Each time a client creates a MessageProducer, it defines a new sequence of messages that have no ordering relationship with the messages it has previously sent." RRBJMSBindingInvoker creates a new MessageProducer for each outbound request. This means the client can't be assured of ordered delivery, even if all other JMS requirements are met (i.e. same destination, same reliability level, etc.). I think binding.jms needs to be able to serially reuse the same MessageProducer for a given reference. Obviously this implies reusing the underlying connection and session as well. I think it should be possible to maintain order across different operations. If I invoke operation A and then operation B on a JMS reference, I expect the message for operation A to be queued before the message for operation B. Of course this assumes that operations A and B are sent using the same reliability level and under the same transaction. So I think a given reference might need to have several active MessageProducers, because different operations might have different reliability levels or different transactional behavior. So for example a sequence of outbound requests to operations that all require reliable, transactional delivery would use one MessageProducer, while another sequence of outbound requests to operations that all require reliable but non-transactional delivery would use another MessageProducer, and so on. It seems like a binding.jms reference would need to reuse a MessageProducer according to the following criteria: * thread of control * transaction on thread * reliability level in JMS header * destination (could vary on callback refs) In a server environment, the reference binding provider needs a hook point to be notified when the component dispatch completes. The server may be pooling JMS connections and sessions. The resources cannot be held beyond the transactional scope of the component. This is tricky to solve. Basically the reference needs to insert itself into the component service dispatch chains. Further it needs to be at the operation invocation chain level, because there may be a NonBlockingInterceptor on that chain, and any cleanup needs to be on the service-side thread. Perhaps this can be done using a RuntimeWireProcessor that adds an interceptor if there are binding.jms references, and the interceptor would call to the reference binding provider to close all the open JMS resources for that reference on the current thread. (I imagine this would be generalized to be useable by any binding, not just JMS.) Comments?
