Hi Peter,

On 16 Nov 2005, at 22:46, Peter Smith wrote:

Hello Rob,

Thank you very much for taking the time to reply. It helped a lot.

Just a couple of quick follow up questions:

1. I see that you've already fixed the problem in the onEvent method (you guys are pretty fast...) but do you mind if I report it as a JIRA issue anyway (you can close it immediately)? You see, my participation via JIRA and reporting real issues is useful when I try to justify to my manager how much time I am spending looking at ServiceMix code.
No not at all - please do. It's great that you've spent the time!

2. Part of my interest in the JMSFlow is because in a past life I had something to do with a JMS implementation. So I'm always wondering "how could I rip out ActiveMQ and substitute some other JMS provider in this code". So from that perspective I wondered why JMSFlow is using ActiveMQ proprietary stuff (like those ConsumerAdvisors) instead of going for some JMS spec compliant equivalents. For example, I finally managed to configure my own JMS provider for the JMS in/out bindings so now I don't really want to be forced to use ActiveMQ just for the JMSFlow. Any comment?
Which JMS provider if you don't mind me asking ?
The only specific part to ActiveMQ is the subscriber notification - and ActiveMQ notifies of already existing subscribers on a particular destination. So if the provider you have in mind supports this - then it should be straightforward - else we'd have to implement some keep-alive/subscriber notification protocols on top of JMS to try and keep it generic. 
Servicemix also re-uses some util classes from ActiveMQ (like the GUID generation etc) - so the ActiveMQ jars would still be required - and it's a nice and fast implementation which supports different topologies, from peer based, hub n' spoke, networks, clusters etc - so we'd still keep ActiveMQ as the default

Thanks again.
Peter.

cheers,

Rob

Rob Davies wrote:
Hi Peter,

answers in-lined at the bottom ...
On 16 Nov 2005, at 05:00, Peter Smith wrote:

Geez...this is probably going to cause somebody a headache. I'm sorry about that - I am just trying to understand how the architecture works

This email is specifically about the JMSFlow NMR flow type. I am looking at the ServiceMix 2.0.1 JMSFlow code revision 749 which is latest AFAIK. Unfortunately I am not in a position to be running this yet, which means all this email is based just on me staring at the code for a couple of hrs...

If somebody who knows the implementation details could go through this and confirm my understanding of JMSFlow  it would be a big help.

Here goes....

My understanding of JMSFlow
======================
  • There is a main broadcast Topic and a number of Queues (container specific Queues & Queues for each component)
    • Topic is for broadcasting changes to remote containers
      • Also for getting advisories if remote container activated/deactivated
    • Queue (per component) is for routing messages to...
    • Queue (container) is also for routing messages...
  • The JMSFlow instance seems to be the sole JMS MessageListener for all these Queues/Topics
  • The JMSFlow is also an ActiveMQ ConsumerAdvisoryEventListener meaning it is notified of the start/stop of Consumers for the broadcast Topic - ie when some other container runs the JMSFlow init/shutdown

  • onMessage - JMS MessageListener for Queues/Topic
    • ObjectMessage might be a MessageExchangeImpl (for message routing) OR a ComponentPacketEvent (notifying some change in a remote component)
    • If ComponentPacketEvent
      • add/update/remove local knowledge of the remote component depending on the ComponentPacketEvent status
    • If MessageExchangeImpl
      • AbstractFlow.doRouting does message routing for the incoming message to some local component

  • onEvent(ConsumerAdvisoryEvent event). I think this is called when some remote Consumer (ie container/JMSFlow instance) of the Topic starts/stops
    • If remote consumer is stopping
      • trash all knowledge of the container components for the remote container that is leaving
    • If remote consumer is starting
      • call onEvent(ComponentPacketEvent) for ALL of the LOCAL container components. I think the main purpose of this is to make use of the side effect to tell the remote container all the components that are available to it from this local container. Presumably it there were a dozen container then remote container 'X' is started then all the other dozen would be advised that 'X' had started and they would madly broadcast their respective components to the Topic so container 'X' would learn about them.

  • onEvent(ComponentPacketEvent event)
    • I think this is called when a LOCAL component is activated/deactivated
    • Each component has a Queue associated with it and the JMSFlow instance is the message listener for this Queue [see onMessage]
      • Activation makes queue & consumer
      • Deactivation closes the consumer for that component Queue

  • doSend/doRouting - routing for outgoing messages...
    • ObjectMessage send to either Queue for container or Queue for specific component

QUESTIONS
==========
  • In the init() method, how come the connection.start is called prior to setting up the message listeners. Maybe it makes no difference - just curious.
This doesn't make any difference - it's just habit on my part.
  • I am a bit confused by the terminology "remote" used throughout JMSFlow? Does it make any difference at all to JMSFlow if the container (ie JMSFlow instance) is on another machine versus just another container instance on the same machine. I think there is no distinction - is that true?
That's correct - it doesn't make any difference to JMS where the other instances of the JMSFlow are. However, the remote - methods are dealing with ComponentPackets that are received from the broadcast topic - so it's to make the distinction between locally activated packets and ones created by other instances.
  • If I understand the onEvent(ConsumerAdvisoryEvent event) method correctly then that will mean that if a lot of containers get started, then the same ComponentPacketEvents will be sent to the broadcast Topic a number of times. That would mean most of the (already started) containers will be told again and again about remote components that they already know about. Is that true? How is the addRemotePacket method is accounting for this scenario (???)
Yes this is true - but the ComponentRegistry only gets updated if it doesn't already know about the activation of the Component
Quite a few JMS vendors allow for dynamic creation of destinations (topics/queues) - ActiveMQ does this - and as the JMSFlow is dependant on ActiveMQ (the advisories are outside the JMS spec) - I decided to use this feature.

  • If onEvent(ConsumerAdvisoryEvent event) is called whenever some remote container starts, but because it in turn calls onEvent(ComponentPacketEvent event) pretending to ACTIVATE local components won't it just end up creating the same queues for the local components over and over and over again (???)
Yep! Bug! Well spotted. The affect of this doesn't affect functionality (as The Queue's don't created until a message is sent to them) but it is a memory leak.
  • I don't really understand the distinction of routing the message to Queue (destination = INBOUND_PREFIX + componentName;) or Queue (destination = INBOUND_PREFIX + id.getContainerName();). Can you explain why the difference? It seems to be something like the "request" going to the remote container Queue, and the "response" is going to the component specific Queue - but why and what difference does it make since either way the remote MessageListener is the same isn't it?
The routing is done this way because queue's will load balance delivery of MessageExchanges. So you can have multiple component instances listening to the same Queue. However, the response needs to be sent back to the component that sent the exchange - as the sender could have sent the exchange synchronously  - and is waiting for a response.

Congratulations if you managed to read this far ;-) And thanks so much for any help in my understanding of this flow type.

Cheers,
Peter.

Thank you Peter!

cheers,

Rob



Reply via email to