[rabbitmq-discuss] New exchange type

Matthias Radestock matthias at lshift.net
Tue Apr 22 06:16:01 BST 2008


Kyle,

Kyle Salasko wrote:
> Recently I put together a new exchange type for RabbitMQ, because none of
> the existing ones completely match our requirements. The problem it solves
> is this: we want a publish-subscribe model where exactly one subscriber
> receives any given message. If we set up a topic exchange and have all
> subscribers listen on the same queue, we get this out of the box. But this
> requires that all messages go to that one queue, which resides on one
> machine, causing a pretty significant bottleneck. A reasonable way around
> this was to implement a new exchange type ("anycast") that picks a random
> queue when a message is routed. The diff and new file for
> rabbit_exchange.erl are attached.
> 
> I'm very new to erlang, so feedback/comments/optimizations are extremely
> welcome.

This looks pretty good and implements a useful feature.

It occurred to me that rather than introducing a new exchange type one 
could place an indicator in the exchange arguments that turns any 
exchange from a multicast to an anycast exchange. That has two advantages:

- we stay entirely within the defined protocol standard

- the user can select the most appropriate matching logic with the 
exchange type, rather than being constrained to topic-based matching


Re optimisations: I haven't done any profiling on this, but I believe 
erlang:now + random:seed are quite expensive, so it is costly to call 
them every time a message is routed. I can think of three ways of fixing 
that:

- don't call now+seed at all. That will result in the generated sequence 
being the same for all publishing channels, which may or may not be a 
problem

- call now+seed on channel creation. During normal operation channels 
are the only processes invoking the routing code, so this catches all 
the interesting cases.

- use a flag in the process dictionary to indicate whether the random 
number generator has been seeded. Check/set that flag in your current 
code that invokes random:uniform. This has the same effect as the 
previous approach but is a less intrusive change since you don't need to 
touch any other modules.


Matthias




More information about the rabbitmq-discuss mailing list