Thanks Martyn. If the uniqueness is a thing not to worry, I can remove this and it will be much simpler.
Howard On Thu, Apr 6, 2017 at 6:39 PM, Martyn Taylor <[email protected]> wrote: > Hi Howard, > > I was going to reply in line, but I think there's a fundamental assumption > you've made that's caused some confusion], so I'll reply here. > > The purpose of FQQN is not to change the uniqueness of queue names across > addresses. Each queue must have a globally unique name. Instead, the > change is required as we've adopted a new addressing model, that creates > consistency across all the protocols. In order to make this happen, a > client wanting to connect to a queue with name "foo" with address > "address", no longer subscribes to the queue name, it actually subscribes > to the "address". This is where the ANYCAST and MULTICAST routing types > fit in. To define queue like behaviour on the broker for an address > "address". You define the following: > > <address name="address"> > <anycast> > <queue name="foo" > ... > > There is a caveat, that right now, because of simplistic logic around how > to determine which queue to bind a client to (if an anycast address has >1 > queue), we require that the queue name match the address. So for JMS you > currently need to define you queue like this: > > <address name="address"> > <anycast> > <queue name="address" > ... > > FQQN has a number of other use cases. Let's say you want shared > subscription like behaviour across your (non JMS 2.0) clients. You can use > FQQN to do this, simply consume from "address::myUniqueQueue" in each of > your clients. > > <address name="address"> > <multicast> > <queue name="myUniqueQueue"> > .... > > There are other use cases in the documentation, so I'll not repeat here. > > Long story short, you don't need to add any complex logic to handle the > "non uniqueness" of queue names. Just parse the FQQN in the OpenWire > protocol, get the queue and address part, then do normal queue lookup on > the broker. This has already been implemented for AMQP, look at the > ProtonServerSender/ReceiverContext for examples. > > Cheers > > On Thu, Apr 6, 2017 at 4:41 AM, Howard Gao <[email protected]> wrote: > > > So I've been doing this FQQN support (ARTEMIS-1093) and I'd like > > to share my thoughts and current implementations of key functionalities, > > as well as some concerns. I'd appreciate any comments > > and adivces to make it better. > > > > More details about FQQN concepts please see official doc: > > https://github.com/apache/activemq-artemis/blob/master/ > > docs/user-manual/en/address-model.md#fully-qualified-queue-names > > > > Simply put, a FQQN takes form of <address>::<queue name>. It uniquely > > and explicitly identifies a 'queue' entity within a broker. With FQQN > > any clients can have access to any 'core' queues, so long as the > addresses > > and queue names are known to them. > > > > For example, if a core queue "q1" is deployed on address "address1", its > > FQQN would be "address1::q1". A JMS consumer can receive messages that > > routed > > to "q1" by referencing the queue directly using its FQQN, as illustrated > > in the following code snippet: > > > > ... > > Queue q1 = session.createQueue("address1::q1"); > > MessageConsumer consumer1 = session.createConsumer(q1); > > Message m = consumer1.receive(2000); > > ... > > > > Before FQQN, clients using any protocols only can access a queue by its > > name, which must be unique across all addresses within a broker. If we > > implement FQQN based on this uniqueness restriction, we don't need change > > any internal bindings management code. Simply removing the address prefix > > (like "address1::" in FQQN "address1::q1") from client requests and every > > thing would work just fine. > > > > However, with FQQN in place it is possible that queues of same names can > be > > created on different addresses while still won't lose their uniqueness. > > For example, "address1::q1" and "address2::q1" are two distinct queues > and > > can perfectly live within a broker together. > > In this case, a client trying > > to access one of the queues can't just simply specify the queue name > "q1". > > Because the broker wouldn't know which queue it refers to (ambiguity). > > > > To solve this issue, I need to add some 'extra' logic to the existing > > binding management. Here is what I do: > > (PR: https://github.com/apache/activemq-artemis/pull/1172 ) > > > > 1. Inside broker it used a map (SimpleAddressManager.nameMap) to store > > bindings (queues) and the keys are queue names. As queue names will no > > longer be guaranteed to be unique with FQQN, a composite key (BindingKey) > > is introduced so that the address part of the queues will paticipate in > > key 'hash' and 'equals' calculation. > > > > 2. In order to detect 'ambiguous' binding queries, a new map called > > uniqueNameMap is added to SimpleAddressManager to keep the number of > > addresses a binding is bound to. For example if a queue "q1" is bound to > > both addresses "address1" and "address2", the number stored in this map > for > > "q1" is 2 ("q1"->2). > > > > When a binding is added these two maps gets updated. > > To understand how it works consider the following scenarios: > > > > In all of the scenarios below suppose the broker have 3 queues > > "address1::q1", "address1::q2", "address2::q1" > > > > [Scenario 1] A client comes in requesting access to a queue by its name > > "q2". > > Broker first checks the uniqueNameMap and finds that there is only > > one binding for this queue name, no ambiguity, and it goes ahead to > > get the binding from nameMap and returns it. > > > > [Scenario 2] A client comes in requesting access to a queue by its FQQN > > "address2::q1". Because FQQN is used we don't need to check ambiguity > > this time. it therefore goes directly to find the binding in nameMap > > and returns it. > > > > [Scenario 3] A client comes in requesting access to a queue by its name > > "q1". > > Because there are two bindings (queues) bound to different addresses and > > client doesn't use FQQN, broker checks the uniqueNameMap and finds that > > there are more than one (two in this case) bindings exists by the same > > queue name, in which case it can't determine which one is the one needed. > > So it gives a warning message and returns null result. > > > > Some concerns with my implementation: > > > > 1) Although the logic seems straightforward, but the actual code looks > > like a bit too complex, as some folks pointed out. I'm currently seeking > > a way to make it simple. Probably separating it into smaller tasks? > > > > 2) String manipulations (like concat() and String/SimpleString > conversions) > > added performance cost. Need a way to minimize the impact. > > > > Again any comments are welcomed. > > > > Thanks, > > Howard > > >
