You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tuscany.apache.org by Greg Dritschler <gr...@gmail.com> on 2009/08/03 19:49:26 UTC

JMS ordered delivery

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?

Re: JMS ordered delivery

Posted by ant elder <an...@gmail.com>.
Chatting about this off list it sounds like the motivation for this is
performance and reducing the overhead of creating a new session for
each request rather than necessarily caring about message order. I've
spent a bit of time reading through the JMS spec to see what we care
share when and looking at what we could do in the Tuscany code, but it
would be good to have some specific scenarios of where the current
performance is causing a problem - is it statless or stateless scoped
components, are they one way requests or request-response style
operations, are persistent messages or transactions important etc?

   ...ant

Re: JMS ordered delivery

Posted by ant elder <an...@gmail.com>.
On Thu, Aug 6, 2009 at 4:59 PM, ant elder<an...@gmail.com> wrote:
> On Mon, Aug 3, 2009 at 6:49 PM, Greg
> Dritschler<gr...@gmail.com> wrote:
>> 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."
>>
>
> I'll comment further in another email but one question here - I
> couldn't find that quote, which spec and version/line number is it
> from?
>
>   ...ant
>

Answering my own question - thats from the JMS API v1.1 specification,
setion 4.6.

As an FYI the other SCA spec references related to this are: JMS
binding spec CD02 rev4 line 431-435 says the JMS binding MAY support
the "ordered" policy intent which is described in the SCA Policy spec
1.1 CD02 line1827 and another relevant section at 1899.

As the JMS binding only says "MAY support" one easy way to deal with
this is just say Tuscany doesn't. That doesn't seem such a bad thing
to me as the whole idea of message order in JMS especially when trying
to apply it across multiple clients and services is full of problems.

   ...ant

Re: JMS ordered delivery

Posted by ant elder <an...@gmail.com>.
On Mon, Aug 3, 2009 at 6:49 PM, Greg
Dritschler<gr...@gmail.com> wrote:
> 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."
>

I'll comment further in another email but one question here - I
couldn't find that quote, which spec and version/line number is it
from?

   ...ant

Re: JMS ordered delivery

Posted by Simon Laws <si...@googlemail.com>.
Ok, so following up on this a bit.

I still don't think that JMSDeliveryMode can be varied on an operation
by operation basis

I can just about buy the point about transaction being specified on
and operation by operation basis but it's not clear that the spec is
excplicity about this. Also seems like a strange thing to do.

So putting these two issues aside it is still the case that we would
have to store the JMS resources on a thread by thread basis.

For stateless components this should be straighforward as a new
component instance is created for each thread. We'd have to change the
way the JMS binding works in order to cache the JMSContext on the
basis of the invoker as opposed to each invoke.

For composite scoped components things are a little different as
multiple threads can be active in the same component instance at the
same time. We would have to have a cache of JMSContext in the invoker
indexed by thread. We would also need some code in the implementation
invoker to clear the cache, and hence release the JMS resources, when
the thread of control leaves the component.

It feels like the same solution will work in both stateless and
stateful cases but we would end up with a bit of over engineering of
the cache in the stateless case. Probably better to aim for
consistency over scope specificity in the binding though.

Thoughts anyone?

Simon

Re: JMS ordered delivery

Posted by Simon Laws <si...@googlemail.com>.
So to move this on a little bit further here's a scenario we could use
(apologies if the intents don't make sense here)...

<component name="Component1">
    <implementation.java class="Component1Impl"
requires="managedTransaction.global"/>
    <reference name="reference1" requires="propogatesTransaction">
        <binding.jms>
             <destination name="DestQueue"/>
             <response>
                   <destination name="RespQueue"/>
             </response>
            <headers JMSDeliveryMode="PERSISTENT"/>
        </binding.jms>
    </reference>
</component>

<component name="Component2">
    <implementation.java class="Component2Impl"
requires="managedTransaction.global">
        <operation name="operationA" requires="???"/>
        <operation name="operationB" requires="???"/>
    </implementation.java>
    <service name="Service2" requires="propogatesTransaction">
        <binding.jms>
               <destination name="DestQueue" create="always"/>
               <response>
                   <destination name="RespQueue" create="always"/>
               </response>
        </binding.jms>
    </reference>
</component>

class Component1Impl implements Component2 {
  @Reference
  protected Component2 reference1;

  public void doABeforeB (){
     reference1.operationA();
     reference2.operationB();
  }

  public void doBBeforeA (){
     reference1.operationB();
     reference2.operationA();
  }
}

Now I know very little about the SCA transaction specifications to
I'll have to read up but I'd like some help in understanding the
details of what you are saying in the original post in the context of
a scenario like the one stated here. From the original post

> 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.

How are different operations called through the same reference
configured with different reliability levels?
How are different operations called through the same reference
configured with different transactional behaviour?

In the Component1 implementation I can see that, assuming non-REQUEST
scope, multiple threads of control can be active in the
implementation. If we wanted to maintain the same session for the
binding then we would have to do it on a thread by thread basis.

Regards

Simon

Re: JMS ordered delivery

Posted by Simon Laws <si...@googlemail.com>.
Hi Greg

There is quite a lot of complexity in this question and. I suspect,
some subtleties. I'd like us to work up some specific composite based
examples of where ordering is expected to be maintained and where it
isn't. Do you have any in mind already?

Regards

Simon