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.
- 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?
- 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 (???)
- 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 (???)
- 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?
Congratulations if you managed to read this far ;-) And thanks so much
for any help in my understanding of this flow type.
Cheers,
Peter.
|
- [servicemix-dev] JMSFlow architecture questions Peter Smith
-