Skip to content

Commit 1c9568d

Browse files
author
Matthew Sackman
committed
Rather than just querying a single remote node, query them all, and accomodate remote nodes that might be running older versions than ourselves, provided we can find someone who is running the same as us.
I did try just limiting Nodes to Nodes with the rabbit process running on them. That seemed to break the tests, and trying to figure out why by looking at rabbit_mnesia made me want to slit my wrists and other body parts. Thus I wrote more code instead.
1 parent 0d52fab commit 1c9568d

File tree

2 files changed

+42
-11
lines changed

2 files changed

+42
-11
lines changed

src/rabbit_mnesia.erl

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -434,10 +434,9 @@ init_db(ClusterNodes, NodeType, CheckOtherNodes) ->
434434
%% First disc node up
435435
maybe_force_load(),
436436
ok;
437-
{[AnotherNode | _], _, _} ->
437+
{[_ | _], _, _} ->
438438
%% Subsequent node in cluster, catch up
439-
ensure_version_ok(
440-
rpc:call(AnotherNode, rabbit_version, recorded, [])),
439+
ok = ensure_version_ok(Nodes),
441440
maybe_force_load(),
442441
ok = rabbit_table:wait_for_replicated(),
443442
ok = rabbit_table:create_local_copy(NodeType)
@@ -639,14 +638,29 @@ schema_ok_or_move() ->
639638
ok = create_schema()
640639
end.
641640

642-
ensure_version_ok({ok, DiscVersion}) ->
643-
DesiredVersion = rabbit_version:desired(),
644-
case rabbit_version:matches(DesiredVersion, DiscVersion) of
641+
ensure_version_ok(OtherNodes) ->
642+
Desired = rabbit_version:desired(),
643+
Fun = fun (Node, FoundMatch) ->
644+
case rpc:call(Node, rabbit_version, recorded, []) of
645+
{error, _} ->
646+
FoundMatch; %% Node probably isn't fully up.
647+
{ok, NodeVersion} ->
648+
case rabbit_version:compare(Desired, NodeVersion) of
649+
eq ->
650+
true;
651+
gt ->
652+
FoundMatch; %% Remote is just older than us.
653+
_ ->
654+
throw({error, {version_mismatch,
655+
Desired, NodeVersion}})
656+
end
657+
end
658+
end,
659+
FoundMatch = lists:foldl(Fun, false, OtherNodes),
660+
case FoundMatch of
645661
true -> ok;
646-
false -> throw({error, {version_mismatch, DesiredVersion, DiscVersion}})
647-
end;
648-
ensure_version_ok({error, _}) ->
649-
ok = rabbit_version:record_desired().
662+
false -> throw({error, {version_mismatch, Desired}})
663+
end.
650664

651665
%% We only care about disc nodes since ram nodes are supposed to catch
652666
%% up only

src/rabbit_version.erl

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
-module(rabbit_version).
1818

19-
-export([recorded/0, matches/2, desired/0, desired_for_scope/1,
19+
-export([recorded/0, matches/2, compare/2, desired/0, desired_for_scope/1,
2020
record_desired/0, record_desired_for_scope/1,
2121
upgrades_required/1]).
2222

@@ -33,6 +33,7 @@
3333

3434
-spec(recorded/0 :: () -> rabbit_types:ok_or_error2(version(), any())).
3535
-spec(matches/2 :: ([A], [A]) -> boolean()).
36+
-spec(compare/2 :: ([A], [A]) -> ('eq' | 'lt' | 'gt' | 'incomparable')).
3637
-spec(desired/0 :: () -> version()).
3738
-spec(desired_for_scope/1 :: (scope()) -> scope_version()).
3839
-spec(record_desired/0 :: () -> 'ok').
@@ -82,6 +83,22 @@ record_for_scope(Scope, ScopeVersion) ->
8283
matches(VerA, VerB) ->
8384
lists:usort(VerA) =:= lists:usort(VerB).
8485

86+
compare(VerA, VerB) ->
87+
VerAS = lists:usort(VerA),
88+
VerBS = lists:usort(VerB),
89+
VerASPrefixVerBS = lists:prefix(VerAS, VerBS),
90+
VerBSPrefixVerAS = lists:prefix(VerBS, VerAS),
91+
if
92+
VerAS =:= VerBS ->
93+
eq;
94+
VerASPrefixVerBS ->
95+
lt;
96+
VerBSPrefixVerAS ->
97+
gt;
98+
true ->
99+
incomparable
100+
end.
101+
85102
%% -------------------------------------------------------------------
86103

87104
desired() -> [Name || Scope <- ?SCOPES, Name <- desired_for_scope(Scope)].

0 commit comments

Comments
 (0)