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