From 6cceea0cec0b935f5a912ac35dfbc6bb0660d469 Mon Sep 17 00:00:00 2001 From: Simon MacMullen Date: Thu, 18 Oct 2012 12:09:18 +0100 Subject: [PATCH] Attempt at an explanation. --- .../src/rabbit_federation_link.erl | 38 ++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/deps/rabbitmq_federation/src/rabbit_federation_link.erl b/deps/rabbitmq_federation/src/rabbit_federation_link.erl index 49292fb307..f91488b5a0 100644 --- a/deps/rabbitmq_federation/src/rabbit_federation_link.erl +++ b/deps/rabbitmq_federation/src/rabbit_federation_link.erl @@ -338,10 +338,46 @@ bind_cmd0(unbind, Source, Destination, RoutingKey, Arguments) -> routing_key = RoutingKey, arguments = Arguments}. +%% This function adds information about the current node to the +%% binding arguments, or returns 'ignore' if it determines the binding +%% should propagate no further. The interesting part is the latter. +%% +%% We want bindings to propagate in the same way as messages +%% w.r.t. max_hops - if we determine that a message can get from node +%% A to B (assuming bindings are in place) then it follows that a +%% binding at B should propogate back to A, and no further. There is +%% no point in propagating bindings past the point where messages +%% would propagate, and we will lose messages if bindings don't +%% propagate as far. +%% +%% Note that we still want to have limits on how far messages can +%% propagate, limiting our bindings is not enough, since other +%% bindings from other nodes can overlap. +%% +%% So in short we want bindings to obey max_hops. However, they can't +%% just obey the max_hops of the current link, since they are +%% travelling in the opposite direction to messages! Consider the +%% following federation: +%% +%% A -----------> B -----------> C +%% max_hops=1 max_hops=2 +%% +%% where the arrows indicate message flow. A binding created at C +%% should flow to B, then to A, and no further. Therefore every time +%% we traverse a link, we keep a count of the number of hops that a +%% message could have made so far, and still propagate. When this +%% number (<<"hops">> below) reaches 0 we propagate no further. +%% +%% hops(link(N)) is given by: +%% +%% min(hops(link(N-1))-1, max_hops(link(N))) +%% +%% In other words, we count down to 0 from the link with the most +%% restrictive max_hops we have yet passed through. + update_binding(Args, #state{downstream_exchange = X, upstream = Upstream}) -> #upstream{max_hops = MaxHops} = Upstream, - %% TODO explain this! Hops = case rabbit_misc:table_lookup(Args, ?BINDING_HEADER) of undefined -> MaxHops; {array, All} -> [{table, Prev} | _] = All,