Permalink
Browse files

Support non-overlapping application distribution nodes

Currently all known nodes should have the same value for the
kernel application's 'distributed' environment variable.  It
is not expected that any application will be distributed on
on more than one set of nodes.

It should be possible to distributed an application between
multiple non-overlapping sets of nodes.  For example with this
system configuration file on nodes a@a and b@b:

   [{kernel,
      [{distributed, [{app_no, [a@a, b@b]}]},
       {sync_nodes_optional, [a@a, b@b]},
       {sync_nodes_timeout, 5000}]}].

... and this system configuration file on nodes c@c and d@d:

   [{kernel,
      [{distributed, [{app_no, [c@c, d@d]}]},
       {sync_nodes_optional, [c@c, d@d]},
       {sync_nodes_timeout, 5000}]}].

Other applications may be distributed involving some other
combination of these nodes without interference.

This patch adds checks in dist_ac to ignore DAC protocol
messages of an application from nodes not included in that
application's distribution specification locally.
  • Loading branch information...
1 parent 7fd1f9b commit 61f4da70e32bf745d96455b6d2f2ca42c4e4a3a7 @vances committed May 3, 2013
Showing with 290 additions and 86 deletions.
  1. +13 −7 lib/kernel/src/dist_ac.erl
  2. +254 −58 lib/kernel/test/application_SUITE.erl
  3. +23 −21 lib/kernel/test/ch.erl
View
@@ -512,8 +512,16 @@ handle_info({dist_ac_new_node, _Vsn, Node, HisAppls, []}, S) ->
{noreply, S#state{appls = NAppls, known = [Node | S#state.known]}};
handle_info({dist_ac_app_started, Node, Name, Res}, S) ->
- case {keysearch(Name, #appl.name, S#state.appls), lists:member(Name, S#state.started)} of
- {{value, Appl}, true} ->
+ ResAppl = keysearch(Name, #appl.name, S#state.appls),
+ ResDistHere = case ResAppl of
+ {value, Tappl} ->
+ lists:member(Node, flat_nodes(Tappl#appl.nodes));
+ false ->
+ false
+ end,
+ ResStarted = lists:member(Name, S#state.started),
+ case {ResAppl, ResDistHere, ResStarted} of
+ {{value, Appl}, true, true} ->
Appls = S#state.appls,
NId = case Appl#appl.id of
_ when element(1, Res) =:= error ->
@@ -545,7 +553,7 @@ handle_info({dist_ac_app_started, Node, Name, Res}, S) ->
{ok, NewS2} ->
{noreply, NewS2}
end;
- {_, _} ->
+ {_, _, _} ->
%% The app has not been started at this node yet; remember this in
%% remote started.
NRStarted = [{Node, Name} | S#state.remote_started],
@@ -1412,10 +1420,8 @@ do_dist_change_update(Appls, AppName, NewTime, NewNodes) ->
%% Merge his Permissions with mine.
dist_merge(MyAppls, HisAppls, HisNode) ->
zf(fun(Appl) ->
- #appl{name = AppName, run = Run} = Appl,
-% #appl{name = AppName, nodes = Nodes, run = Run} = Appl,
-% HeIsMember = lists:member(HisNode, flat_nodes(Nodes)),
- HeIsMember = true,
+ #appl{name = AppName, nodes = Nodes, run = Run} = Appl,
+ HeIsMember = lists:member(HisNode, flat_nodes(Nodes)),
case keysearch(AppName, #appl.name, HisAppls) of
{value, #appl{run = HisRun}} when HeIsMember ->
case keysearch(HisNode, 1, HisRun) of
Oops, something went wrong.

0 comments on commit 61f4da7

Please sign in to comment.