Gordon Sim wrote:
Ted Ross wrote:
Here's the proposal for (1).  I'm calling this "dynamic routing"
because it involves dynamically creating and deleting bindings on the
federation queues.

When a federation route is configured, a subscription is created on
the source broker with the "dest" field set to the name of the
destination exchange.  In a "pull" route, this subscription is
initiated by the destination broker.  The federation code that manages
this subscription can track the local bindings on the dest exchange
and propagate the union of the binding keys to the source exchange.

When you say 'propagate' you mean it will bind a queue it has created on the remote broker (and to which it has subscribed) to the remote exchange so as to have a binding to that queue for each unique binding key defined in the local exchange?
Yes, that is exactly right.

It doesn't take much thought to realize that there is a looping issue
for dynamic bindings much like there is with messages.  The solution,
of course, is also similar in that bind commands have an argument
field that can carry a tag list.  Here are the rules:

1) If a local binding is untagged (i.e. it was created by a local
  consumer), tag the bind request with only the local broker tag
  before propagating it to any source brokers.

2) If a binding is declared and it is tagged with the local broker
  tag, do not apply the binding (silently drop it).

3) If the set of tags changes on an existing binding, re-propagate it
  to all sources.

I _think_ there is a simpler scheme that would work (but perhaps I've misunderstood your description or haven't considered all the cases).

If the bridge that issues the bind requests for a particular route identifies itself and the names of the brokers it has links to (active or not) when it makes that request. Bridges on the broker receiving that request can then ignore that binding if their 'peer' brokers is in that list.
I'm not sure I'm parsing your text correctly but I think it overlooks the multi-hop scenario where a federation binding needs to be propagated to more than one broker.

When a new route is established (because it was just added or because
the remote broker just became reachable), the existing bindings of the
dest exchange must be iterated over for propagation.

There is a problem for which I don't currently have a solution.  The
exchange.unbind command does not have an arguments field so
propagation of unbinds is problematic.  One possibility (admittedly
ugly) is to use a field in the exchange.bind arguments to indicate
that a bind command is to be interpreted as an unbind for the purposes
of propagation.

Can't bridges just track the bindings they have established and then react to unbind on their local broker by unbinding their subscription queue from the remote exchange if necessary? Why would extra tagging be needed? (Apologies if my understanding is overly simplistic here).
Let me answer with an example to illustrate. Consider a "transit-broker" scenario where there are three brokers connected in a star (or "line" ;) configuration:

Assume that the federation is configured as a distributed direct exchange.

   +----+            +----+            +----+
   |    | ---------> |    | ---------> |    |
   | B1 |            | B2 |            | B3 |
   |    | <--------- |    | <--------- |    |
   +----+            +----+            +----+

In this example, clients on B1 and B3 can only communicate with each other through the transit-broker B2.

A client on broker B1 binds key "A" to the exchange:

     A
     |
   +----+            +----+            +----+
   |    | ---------> |    | ---------> |    |
   | B1 |            | B2 |            | B3 |
   |    | <--------- |    | <--------- |    |
   +----+            +----+            +----+

In order for "A" messages to reach the client from anywhere in the network, the binding to A must be propagated to the other brokers in the topology. The federation bindings (those not created directly by a client) are tagged according to the rules.

     A
     |
   +----+            +----+            +----+
   |    | ---------> |    | ---------> |    |
   | B1 |            | B2 |            | B3 |
   |    | <--------- |    | <--------- |    |
   +----+      A(1)  +----+     A(1,2) +----+

Note that when B3 attempts to propagate the binding back to B2, the binding is dropped and propagation stops.

Now a second client, on B2, also binds to "A". The binding propagates outward from B2 and the new configuration of tags is as follows:

     A                 A
     |                 |
   +----+   A(2)     +----+            +----+
   |    | ---------> |    | ---------> |    |
   | B1 |            | B2 |            | B3 |
   |    | <--------- |    | <--------- |    |
   +----+      A(1)  +----+      A(2)  +----+

Note that the binding from B3 to B2 no longer has the "1" tag.

If the client on B2 were to unbind "A", simply propagating the the unbind outbound will correctly remove the binding on B1 but will incorrectly remove the binding on B3. There has to be more intelligent discrimination as to which bindings to modify in a bind/unbind scenario.

Having gone through this exercise, I think I'm seeing a solution to my no-arguments-in-unbind problem. More on this later...

-Ted

Reply via email to