[rabbitmq-discuss] rabbitmq-c: amqp_exchange_declare() always sets auto-delete to no

Lowell.Boggs at emc.com Lowell.Boggs at emc.com
Thu Jul 7 15:30:19 BST 2011


Thanks,

Your description of what I am trying to do is exactly right and your suggestion seems reasonable.  I'll adjust my design accordingly.

Thanks for taking the time to help.

Lowell
 

-----Original Message-----
From: David Wragg [mailto:david at rabbitmq.com] 
Sent: Wednesday, July 06, 2011 5:35 PM
To: Boggs Jr., Lowell
Cc: rabbitmq-discuss at lists.rabbitmq.com
Subject: Re: [rabbitmq-discuss] rabbitmq-c: amqp_exchange_declare() always sets auto-delete to no

Hi Lowell,

<Lowell.Boggs at emc.com> writes:
> Is there a reason that you cannot create an exchange with the
> auto_delete property == true?

Auto-delete on exchanges is a AMQP 0-8 feature that is deprecated in
AMQP 0-9-1.  This is why the amqp_exchange_declare function does not
expose it (ever since it was converted to AMQP 0-9-1).

> Is it safe for me as an application devloper to create a clone of this
> function that has the auto_delete property passed in?  Does the
> rabbitmq team have plans to change the way the underlying functions
> work?

It is safe, but not a good idea.

rabbitmq-server still supports AMQP 0-8, including the auto-delete
property on exchanges.  So if you copy amqp_exchange_declare and add
that parameter, it will work today.  But at some point, rabbitmq-server
may drop AMQP 0-8 compatibility, and then it would stop working.

> Is a temporary exchange even a good idea?

Not really.

> I am trying to simplify the shutdown logic of a multi-threaded
> application.  I don't want to have to invent a way of signaling my
> worker threads to shut down.  Instead, I want to send them a message
> that they can read like normal but have a quick way of identifying
> that this is a shutdown command. I am currently writing code for my
> threads that work like this:
>
> void Thread()
> {
>
>     // create the connection
>     // declare the primary command exchange
>     // declare the qrimary queue
>     // declare a "stop command" exchange
>     // declare a "stop command" queue
>     // bind everyone up and call basic_consume on the queues
>
>
>     for(;;)
>      {
>         string exchangeName;
>         string topicName;
>         string messageBody;
>
>          int error = readMessage(exchangeName, topicName, messageBody);
>
>          if(error) break;
>
>         if(exchangeName == "stop")
>            break;
>
>        processMesage(messageBody);
>
>     }
> }
>
> Note that I am having multiple threads in multiple executables on
> multiple machines all reading from the same primary command exchange
> for performance and redundancy reasons -- so I can't really use the
> topic to indicate shutdown.  I might want to shutdown a given
> executable on a given host, not the entire system.
>
> The above logic is working fine, but when I kill a process, I have to
> remember to delete the exchanges because they don't have an autoDelete
> flag.
>
> Is there a better way to handle this shutdown logic?

It sounds like you have a hierarchy of threads, processes, and machines.
And you want to send command messages (including shutdown messages) to
the various levels in that hierarchy: To a thread, to all the threads
in a process, to all the threads in all processes on a host, and to all
threads everywhere.

You can accomplish this by declaring four exchanges. Let's call them
"per-thread", "per-process", "per-host" and "everything".

Each thread declares an auto-delete queue for itself, and binds this
queue to all four exchanges, but with different binding keys.

"per-thread" should be a direct exchange.  A thread binds its queue to
this exchange  with a binding key of the form "<host_id>.<process_id>.<thread_id>".

"per-process" should be a direct exchange.  A thread binds its queue to
this exchange with with a binding key of the form
"<host_id>.<process_id>".

"per-host" should be a direct exchange.  A thread binds its queue to
this exchange with with a binding key of the form "<host_id>"

Finally, "everything" can just be a fanout exchange (and so the binding
key is not used).

In order to send a command, use the exchange for the appropriate level
in the hierarchy, and the corresponding routing key.

Because all four exchanges are long lived, your code should not need to
delete any of them.

-- 
David Wragg
Staff Engineer, RabbitMQ
VMware, Inc.


More information about the rabbitmq-discuss mailing list