On 17/02/14 18:13, CLIVE wrote:
Fraze,
It's with an "s" :-)
Thanks for taking a further look at this. I have not come across the
selector option before. In fact I tried it today at work on a 0.20
version, but got an exception due to this option not being a valid
name. Currently building 0.26 and will give it another go tomorrow.
Just one thought, as the selector is part of the link section, will
this still work if the receivers are all in the same process, using a
single session. I had hoped to try this today but ran out of time
waiting for the 0.26 version to build.
To be honest I've not tried this I've only just started messing with
this stuff myself over the last few weeks (you might have seen my post
"A write up of some AMQP 1.0 Experiments") and I've mainly been using
spout and drain for simplicity so I didn't have to write any code :-)
As it happens using Selectors with a queue node wasn't something I'd
tried at all until I saw your post, so I figured I might as well have a
play and was quite pleased that at face value it seems to be doing
something fairly close to your use case :-)
To answer your question though I'm no AMQP 1.0 expert but in the AMQP
1.0 specification section 2.1.2 figure 2.9 illustrates a class diagram
of communication endpoints and that shows multiplicities as follows:
+-------------+
| Link | Message Transport
+-------------+ (Node to Node)
| name |
| source |
| target |
| timeout |
+-------------+
/|\ 0..n
|
|
|
\|/ 0..1
+------------+
| Session | Frame Transport
+------------+ (Container to Container)
| name |
+------------+
/|\ 0..n
|
|
|
\|/ 1..1
+------------+
| Connection | Frame Transport
+------------+ (Container to Container)
| principal |
+------------+
In other words the Session to Link multiplicity is 0..n which *suggests*
that it should "still work if the receivers are all in the same process,
using a single session". Worst case scenario would be you might need
different sessions, but I suspect that it'll probably be fine. I think
that it's just a case of calling createReceiver with the appropriate
address - I think that the receiver in AMQP 1.0 terms is a terminus,
which *does* have an association with the Link unlike your previous
thought process where you assumed that the bindings had an association
with the receiver (which they don't).
Oh one thing that I've not actually tried is what happens if something
is on your single queue *ahead* of things you care about - so what
happens if you have bob/bill/tim selectors and you send a message with
the subject "freddy" ahead of the message with the subject "tim" (if you
see what I mean).
I can't try it out at the moment because I currently can't compile off
trunk 'cause something is broken :-(
You've hopefully also seen my posts that relate to the "subject" - it
works fine in AMQP 0.10 using "qpid.subject" but in AMQP 1.0 it's part
of the immutable properties and has a specific accessor - it should be
fairly easy to add support if people think it's useful though.
Will be looking at AMQP 1.0 over the next few weeks.
Anyway thanks for all the advice and help so far.
Clive
No worries, hope it has been useful - helps me learn more stuff too :-)
FWIW though I'm *still* not convinced that producers delivering
everything to the same queue is the best idea if you've got a mixture of
fast and slow producers writing to the same queue you run a risk of the
fast producers "bullying" the messages of the slower one, I'm not sure
what you have against queues. FWIW even if you configure a queue with
say 2GB capacity that capacity is only used if the queue is actually
full so 100*1MB queues or 1*100MB queue you still need sufficient
capacity to cope with producer burstiness or consumers dying.
In your earlier mail you said:
So at run time you have no way of knowing what address strings are going
to be passed to you.
The User application then makes the following calls on your API
Messaging.registerUserCallback( "queue1; {create: receiver, node:
{x-declare:{auto-delete:true}, x-bindings: [{exchange: 'amq.topic',
queue: 'queue1', key: 'bill'}]}}" ,usrCallback1);
Messaging.registerUserCallback( "queue2; {create: receiver, node:
{x-declare:{auto-delete:true}, x-bindings: [{exchange: 'amq.topic',
queue: 'queue1', key: 'ben'}]}}" ,usrCallback2);
The User application might not make a call with an address string that
references the same queue, but as a good API designer, you need to be
able to handle it.
I'd argue that in this case you've not *really* got your own API, you've
just added a convenient abstraction around qpid::messaging, in which
case you've not actually really abstracted users away from having to
supply Address Strings that are semantically correct.
As explained in previous responses people supplying the address strings
would *still* need to be aware that the x-bindings associated a queue
with an exchange and were actually unrelated to the receiver.
To make it a true API that abstracts that stuff you do need to have
application code.
Given that you've discovered that using selectors has a different syntax
and indeed with AMQP 1.0 the way you're using topic matches changes too
(do read the post I mentioned above) you just might want to provide a
true API to abstract this where your registerUserCallback() takes a
queue name a key and a callback - just a thought.
Cheers,
Frase