Skip to content

Instantly share code, notes, and snippets.

@Vagabond
Created November 12, 2010 19:42
Show Gist options
  • Save Vagabond/674561 to your computer and use it in GitHub Desktop.
Save Vagabond/674561 to your computer and use it in GitHub Desktop.
gen_leader netsplit diff
diff --git a/hanssv+serge_version/gen_leader.erl b/hanssv+serge_version/gen_leader.erl
index 036e2a6..c0808b1 100644
--- a/hanssv+serge_version/gen_leader.erl
+++ b/hanssv+serge_version/gen_leader.erl
@@ -555,7 +555,9 @@ safe_loop(#server{mod = Mod, state = State} = Server, Role,
%% A DOWN message should arrive to solve this situation
safe_loop(Server,Role,E,Msg)
end;
-
+ {election} = Msg ->
+ %% We're already in an election, so this is likely an old message.
+ safe_loop(Server, Role, E, Msg);
{heartbeat, _Node} = Msg ->
%% io:format("Got {heartbeat, ~w} - ~w (safe_loop)\n", [_Node, E#election.leadernode]),
safe_loop(Server,Role,E,Msg);
@@ -605,6 +607,7 @@ safe_loop(#server{mod = Mod, state = State} = Server, Role,
case ( pos(Node,E#election.candidate_nodes) <
pos(node(),E#election.candidate_nodes) ) of
true ->
+ NewServer = Server,
Lesser = lesser(node(),E#election.candidate_nodes),
LesserIsSubset = (Lesser -- NewDown) == [],
case ((E#election.status == wait) and
@@ -622,6 +625,13 @@ safe_loop(#server{mod = Mod, state = State} = Server, Role,
end
end;
false ->
+ case (E#election.leader == self()) of
+ true ->
+ {ok,NewState} = (Server#server.mod):handle_DOWN(Node, Server#server.state, E),
+ NewServer = Server#server{state = NewState};
+ false ->
+ NewServer = Server
+ end,
case ( (E#election.status == elec2) and
(Node == E#election.pendack) ) of
true ->
@@ -637,7 +647,7 @@ safe_loop(#server{mod = Mod, state = State} = Server, Role,
end
end
end,
- hasBecomeLeader(NewE,Server,Msg)
+ hasBecomeLeader(NewE,NewServer,Msg)
end.
@@ -724,6 +734,47 @@ loop(#server{parent = Parent,
false ->
loop(Server,Role,E,Msg)
end;
+ {election} ->
+ %% io:format("Doing an election~n"),
+ Mide = E,%#election{leader = none, leadernode = none},
+ E1 = startStage1(Mide),
+ safe_loop(Server, candidate, E1, Msg);
+ {checklead, Node} ->
+ %% io:format("Checking lead~n"),
+ case (E#election.leadernode == Node) of
+ true ->
+ loop(Server, Role, E, Msg);
+ false when E#election.leader == self() ->
+ Newdown = E#election.down -- [Node],
+ E1 = E#election{down = Newdown},
+ lists:foreach(
+ fun(N) ->
+ {Name, N} ! {election}
+ end, E1#election.candidate_nodes),
+ Mide = E1,%#election{leader = none, leadernode = none},
+ E2 = startStage1(Mide),
+ safe_loop(Server, candidate, E2, Msg);
+ false ->
+ %% io:format("conflict, I'll be getting told by the leader when to start an election~n"),
+ loop(Server, Role, E, Msg)
+ end;
+ {heartbeat} ->
+ case (E#election.leader == self()) of
+ true ->
+ case E#election.down of
+ [] ->
+ loop(Server, Role, E, Msg);
+ _ ->
+ lists:foreach(
+ fun(N) ->
+ {Name, N} ! {checklead, node()}
+ end,E#election.down),
+ timer:send_after(E#election.cand_timer_int, {heartbeat}),
+ loop(Server, Role, E, Msg)
+ end;
+ false ->
+ loop(Server, Role, E, Msg)
+ end;
{heartbeat, _Node} ->
case (E#election.leader == self()) of
true ->
@@ -797,6 +848,7 @@ loop(#server{parent = Parent,
{ok, Synch, NewState1} ->
{NewState1, broadcast({from_leader,Synch}, E1)}
end,
+ {Name, node()} ! {heartbeat},
loop(Server#server{state=NewState}, Role, NewE, Msg);
false ->
loop(Server, Role, E1,Msg)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment