Cheers,

I was fiddling with the Topic examples and I ran into a problem. If I
start the client "ReceiveLogsTopic" before the sender "EmitLogTopic" I
see everything working fine. Sender sends and client receives and
displays right.

However, if I start the sender before the client, the message gets sent
but then nothing happens, the queue appears to be empty and the client
keeps waiting for nothing.

I think that's correct since the queue is created at runtime and is
destroyed when there's nothing more to do with it as explained in the
documentation:

channel.exchangeDeclare(*exchangeName*,*"direct"*,*true*);
String*queueName* = channel.queueDeclare().getQueue();
channel.queueBind(*queueName*,*exchangeName*,*routingKey*);

This will actively declare the following objects, both of which can be
customised by using additional parameters. Here neither of them have any
special arguments.

1. a durable, non-autodelete exchange of "direct" type
2. a non-durable, exclusive, autodelete queue with a generated name



What I would like to do instead is (example):

1)
create 3 exchanges: EXA, EXB and EXC
for every exchange, create 2 queues and bind them to it: Q1 and Q2. All
queues have the same name but are not the same object (see attached PNG
if needed)
2)
send a message to be queued in queue Q1 through EXA
send the same message to be queued in queue Q1 through EXB
message then is queued in two different queues which happen to have the
same name but are binded to different exchanges
3)
poll Q1 through EXA to read messages and delete message
poll Q1 through EXB to read messages and leave message there
message then is no longer in EXA-Q1 but is still available through EXB-Q1

I don't and can't know if and when someone will try to send or read
messages.

I guess it would require me to declare and bind a queue beforehand,
maybe by using 3 classes: setUpExchangeAndQueues, sendMessage,
pollMessages, but I'm a bit at loss here, could anyone point me in the
right direction?

I read that:

If several clients want to share a queue with a well-known name, this
code would be appropriate:

channel.exchangeDeclare(*exchangeName*,*"direct"*,*true*);
channel.queueDeclare(*queueName*,*true*,*false*,*false*,*null*);
channel.queueBind(*queueName*,*exchangeName*,*routingKey*);

This will actively declare:

1. a durable, non-autodelete exchange of "direct" type
2. a durable, non-exclusive, non-autodelete queue with a well-known name

Tried it but failed.

Please advise, I'm going crazy on this.

Thank you,

have a nice day
--
Dr. Stefano Ghio - ENG Engineering Italy

Website: http://groglogs.blogspot.com/

*If you received this message but you are not its recipient, please
ignore it and warn me, thank you.*
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.rabbitmq.com/pipermail/rabbitmq-discuss/attachments/20111114/c323acb7/attachment.htm>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: exq.PNG
Type: image/png
Size: 8402 bytes
Desc: not available
URL: <http://lists.rabbitmq.com/pipermail/rabbitmq-discuss/attachments/20111114/c323acb7/attachment.png>

Search Discussions

  • Marek Majkowski at Nov 14, 2011 at 3:34 pm

    On Mon, Nov 14, 2011 at 12:22, Stefano Ghio wrote:
    I was fiddling with the Topic examples and I ran into a problem. If I start
    the client "ReceiveLogsTopic" before the sender "EmitLogTopic" I see
    everything working fine. Sender sends and client receives and displays
    right.

    However, if I start the sender before the client, the message gets sent but
    then nothing happens, the queue appears to be empty and the client keeps
    waiting for nothing.
    Yes. RabbitMQ doesn't store 'old' messages. After the queue
    is created only 'new' messages will go to it.

    If you need to hear about previous messages, you should
    create queue beforehand.

    If you can't do it (you don't know about consumers while
    you're sending messages), you probably have it solved
    in an application layer - store data in a database
    and query it after the queue was created.
    (beware race conditions there)
    I think that's correct since the queue is created at runtime and is
    destroyed when there's nothing more to do with it as explained in the
    documentation:

    channel.exchangeDeclare(exchangeName, "direct", true);
    String queueName = channel.queueDeclare().getQueue();
    channel.queueBind(queueName, exchangeName, routingKey);

    This will actively declare the following objects, both of which can be
    customised by using additional parameters. Here neither of them have any
    special arguments.

    a durable, non-autodelete exchange of "direct" type
    a non-durable, exclusive, autodelete queue with a generated name

    What I would like to do instead is (example):

    1)
    create 3 exchanges: EXA, EXB and EXC
    for every exchange, create 2 queues and bind them to it: Q1 and Q2. All
    queues have the same name but are not the same object (see attached PNG if
    needed)
    Nope. A queue is identified by a name. The same name= the same
    queue. You can bind multiple exchanges to a queue though,
    and receive data from multiple exchanges on a single queue.
    (also, see some magical properties on received messages,
    you should be able to get routing key and exchange name
    per message)
    2)
    send a message to be queued in queue Q1 through EXA
    send the same message to be queued in queue Q1 through EXB
    message then is queued in two different queues which happen to have the same
    name but are binded to different exchanges
    3)
    poll Q1 through EXA to read messages and delete message
    poll Q1 through EXB to read messages and leave message there
    message then is no longer in EXA-Q1 but is still available through EXB-Q1

    I don't and can't know if and when someone will try to send or read
    messages.

    I guess it would require me to declare and bind a queue beforehand, maybe by
    using 3 classes: setUpExchangeAndQueues, sendMessage, pollMessages, but I'm
    a bit at loss here, could anyone point me in the right direction?

    I read that:

    If several clients want to share a queue with a well-known name, this code
    would be appropriate:

    channel.exchangeDeclare(exchangeName, "direct", true);
    channel.queueDeclare(queueName, true, false, false, null);
    channel.queueBind(queueName, exchangeName, routingKey);

    This will actively declare:

    a durable, non-autodelete exchange of "direct" type
    a durable, non-exclusive, non-autodelete queue with a well-known name

    Tried it but failed.

    Please advise, I'm going crazy on this.
    Sorry, I'm not really following the last part.

    Marek
  • Stefano Ghio at Nov 15, 2011 at 2:39 pm

    If you need to hear about previous messages, you should
    create queue beforehand.
    Done but with issues as my problem lies there:
    /
    />A queue is identified by a name. The same name= the same
    queue. You can bind multiple exchanges to a queue though,
    and receive data from multiple exchanges on a single queue.
    I need to declare one queue for every receiver and bind it to the same exchange but I don't know how many there will be, furthermore everything has to be done at runtime.

    Say I have a client CLIENT0 at t0 which declares:
    - queue A
    - exchange EX

    From its code, I bind EX-A with routing "client.something":

    ConnectionFactory factory = new ConnectionFactory();
    factory.setHost("localhost");
    connection = factory.newConnection();
    channel = connection.createChannel();
    channel.exchangeDeclare("EX", "topic");
    channel.queueDeclare("A", false, false, false, null);
    channel.queueBind("A", "EX", "client.something");

    Now if I send a message:

    [...]
    channel.basicPublish("EX", "client.*", null, message.getBytes());

    it gets queued in queue A and I can read it with:

    [...]
    QueueingConsumer consumer = new QueueingConsumer(channel);
    channel.basicConsume("A", true, consumer);

    Later at t1, two more clients CLIENT1, CLIENT2 show up and declare:
    - queues B, C
    on the same exchange EX

    From their code, I bind EX-B with routing "client.else" and EX-C with routing "another.something" so that I can send messages to both CLIENT0 and CLIENT1 by using routing "client.*", and to CLIENT0 and CLIENT2 using routing "*.something".

    If I now send another message from CLIENT0, it only gets queued in queue A and never goes in queue B or C. Declaring and binding all three queues at time t0 instead works and messages are delivered correctly to the right clients.

    My question is:

    How can I dynamically declare and bind queues to already existing exchanges so that already running senders can continue sending messages as they did before and have them delivered properly?
    Back to my example, I'd like CLIENT0 to keep sending messages routing them with "client.*" and see those messages added in the newly created queue B too after CLIENT1 has declared and binded it. Maybe I need some sort of refresh in CLIENT0?

    Any help is much appreciated,

    have a nice day


    --
    Dr. Stefano Ghio - ENG Engineering Italy

    Website: http://groglogs.blogspot.com/

    *If you received this message but you are not its recipient, please
    ignore it and warn me, thank you.*
    -------------- next part --------------
    An HTML attachment was scrubbed...
    URL: <http://lists.rabbitmq.com/pipermail/rabbitmq-discuss/attachments/20111115/43f9e636/attachment.htm>
  • Stefano Ghio at Nov 15, 2011 at 3:41 pm
    Never mind,

    solved by having every receiver create its own queue at startup and
    sending messages using defined rules common to everyone.

    Send is then done as:

    [...]
    exchangeDeclare(..);
    basicPublish(..);

    Of course sending before the receiver has spawned results in message loss.

    Thanks for your help anyway,

    cheers
    --
    Dr. Stefano Ghio - ENG Engineering Italy

    Website: http://groglogs.blogspot.com/

    *If you received this message but you are not its recipient, please
    ignore it and warn me, thank you.*
    -------------- next part --------------
    An HTML attachment was scrubbed...
    URL: <http://lists.rabbitmq.com/pipermail/rabbitmq-discuss/attachments/20111115/b899aee9/attachment.htm>
  • Marek Majkowski at Nov 15, 2011 at 5:53 pm

    On Tue, Nov 15, 2011 at 15:41, Stefano Ghio wrote:
    Never mind,

    solved by having every receiver create its own queue at startup and sending
    messages using defined rules common to everyone.

    Send is then done as:

    [...]
    exchangeDeclare(..);
    basicPublish(..);

    Of course sending before the receiver has spawned results in message loss.

    Thanks for your help anyway,

    Yes, that's how it should be done.

    I'm happy to hear that you get it working.

    Cheers,
    Marek

    cheers
    --
    Dr. Stefano Ghio - ENG Engineering Italy

    Website: http://groglogs.blogspot.com/

    If you received this message but you are not its recipient, please ignore it
    and warn me, thank you.
    _______________________________________________
    rabbitmq-discuss mailing list
    rabbitmq-discuss at lists.rabbitmq.com
    https://lists.rabbitmq.com/cgi-bin/mailman/listinfo/rabbitmq-discuss

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
grouprabbitmq-discuss @
categoriesrabbitmq
postedNov 14, '11 at 12:22p
activeNov 15, '11 at 5:53p
posts5
users2
websiterabbitmq.com
irc#rabbitmq

2 users in discussion

Stefano Ghio: 3 posts Marek Majkowski: 2 posts

People

Translate

site design / logo © 2022 Grokbase