started making paxos more nack registant
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
fbcd7542fc
commit
249a6e1ae3
@ -56,7 +56,7 @@ defmodule EventualLeaderElector do
|
|||||||
|
|
||||||
{:timeout} ->
|
{:timeout} ->
|
||||||
state =
|
state =
|
||||||
if MapSet.size(state.heard_back) == 0 do
|
if MapSet.size(state.heard_back) < floor(length(state.processes)/2) + 1 do
|
||||||
state
|
state
|
||||||
else
|
else
|
||||||
to_trust = Enum.at(Enum.sort(MapSet.to_list(state.heard_back)), 0)
|
to_trust = Enum.at(Enum.sort(MapSet.to_list(state.heard_back)), 0)
|
||||||
|
58
lib/paxos.ex
58
lib/paxos.ex
@ -42,6 +42,7 @@ defmodule Paxos do
|
|||||||
pid_to_inform: pid_to_inform,
|
pid_to_inform: pid_to_inform,
|
||||||
has_sent_accept: false,
|
has_sent_accept: false,
|
||||||
action: action,
|
action: action,
|
||||||
|
has_sent_prepare: false,
|
||||||
})
|
})
|
||||||
|
|
||||||
%{state | instmap: instmap}
|
%{state | instmap: instmap}
|
||||||
@ -146,7 +147,7 @@ defmodule Paxos do
|
|||||||
} end)
|
} end)
|
||||||
|
|
||||||
true ->
|
true ->
|
||||||
Utils.unicast({:nack, inst, ballot}, proc)
|
Utils.unicast({:nack, inst, ballot, state.instmap[inst].ballot}, proc)
|
||||||
state
|
state
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -157,8 +158,8 @@ defmodule Paxos do
|
|||||||
|
|
||||||
state
|
state
|
||||||
|
|
||||||
{:nack, inst, ballot} ->
|
{:nack, inst, ballot, new_ballot} ->
|
||||||
IO.puts("#{state.name} - nack #{inspect(inst)} #{inspect(ballot)}")
|
IO.puts("#{state.name} - nack #{inspect(inst)} #{inspect(ballot)} #{inspect(new_ballot)}")
|
||||||
|
|
||||||
cond do
|
cond do
|
||||||
has_finished(state, inst) ->
|
has_finished(state, inst) ->
|
||||||
@ -169,14 +170,35 @@ defmodule Paxos do
|
|||||||
send(state.instmap[inst].pid_to_inform, {:abort, inst})
|
send(state.instmap[inst].pid_to_inform, {:abort, inst})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
EagerReliableBroadcast.broadcast(state.name, {:abort, inst, ballot, new_ballot})
|
||||||
|
|
||||||
set_instmap(state, inst, fn map -> %{
|
set_instmap(state, inst, fn map -> %{
|
||||||
map | has_sent_accept: false
|
map | has_sent_accept: false,
|
||||||
|
ballot: new_ballot + 1,
|
||||||
|
has_sent_prepare: false,
|
||||||
} end)
|
} end)
|
||||||
|
|
||||||
true ->
|
true ->
|
||||||
state
|
state
|
||||||
end
|
end
|
||||||
|
|
||||||
|
{:rb_deliver, _proc, {:abort, inst, ballot}} ->
|
||||||
|
cond do
|
||||||
|
has_finished(state, inst) ->
|
||||||
|
state
|
||||||
|
|
||||||
|
state.instmap[inst].ballot == ballot ->
|
||||||
|
if Map.has_key?(state.instmap, inst) and state.instmap[inst].pid_to_inform != nil do
|
||||||
|
send(state.instmap[inst].pid_to_inform, {:abort, inst})
|
||||||
|
end
|
||||||
|
|
||||||
|
state
|
||||||
|
|
||||||
|
true ->
|
||||||
|
state
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
{:prepared, inst, ballot, accepted_ballot, accepted_value} ->
|
{:prepared, inst, ballot, accepted_ballot, accepted_value} ->
|
||||||
IO.puts(
|
IO.puts(
|
||||||
"#{state.name} - prepared #{inspect(inst)} #{inspect(ballot)} #{inspect(accepted_ballot)} #{inspect(accepted_value)}"
|
"#{state.name} - prepared #{inspect(inst)} #{inspect(ballot)} #{inspect(accepted_ballot)} #{inspect(accepted_value)}"
|
||||||
@ -225,7 +247,7 @@ defmodule Paxos do
|
|||||||
} end)
|
} end)
|
||||||
else
|
else
|
||||||
IO.puts("#{state.name} -> #{proc} nack")
|
IO.puts("#{state.name} -> #{proc} nack")
|
||||||
Utils.unicast({:nack, inst, ballot}, proc)
|
Utils.unicast({:nack, inst, ballot, state.instmap[inst].ballot}, proc)
|
||||||
state
|
state
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -233,10 +255,11 @@ defmodule Paxos do
|
|||||||
{:accepted, inst, ballot} ->
|
{:accepted, inst, ballot} ->
|
||||||
IO.puts("#{state.name} accepted #{inspect(inst)} #{inspect(ballot)}")
|
IO.puts("#{state.name} accepted #{inspect(inst)} #{inspect(ballot)}")
|
||||||
|
|
||||||
if has_finished(state, inst) do
|
cond do
|
||||||
|
has_finished(state, inst) ->
|
||||||
state
|
state
|
||||||
else
|
|
||||||
if state.leader == state.name and state.instmap[inst].ballot == ballot do
|
state.leader == state.name and state.instmap[inst].ballot == ballot ->
|
||||||
accepted(
|
accepted(
|
||||||
set_instmap(state, inst, fn map -> %{
|
set_instmap(state, inst, fn map -> %{
|
||||||
map
|
map
|
||||||
@ -244,10 +267,10 @@ defmodule Paxos do
|
|||||||
} end),
|
} end),
|
||||||
inst
|
inst
|
||||||
)
|
)
|
||||||
else
|
|
||||||
|
true ->
|
||||||
state
|
state
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
{:get_value, inst, pid_to_inform, t} ->
|
{:get_value, inst, pid_to_inform, t} ->
|
||||||
# IO.puts("#{state.name} get_value")
|
# IO.puts("#{state.name} get_value")
|
||||||
@ -302,6 +325,9 @@ defmodule Paxos do
|
|||||||
Map.get(state.instmap, inst) == nil and Map.get(state.other_values, inst) == nil ->
|
Map.get(state.instmap, inst) == nil and Map.get(state.other_values, inst) == nil ->
|
||||||
state
|
state
|
||||||
|
|
||||||
|
Map.get(state.instmap, inst) != nil and state.instmap[inst].has_sent_prepare ->
|
||||||
|
state
|
||||||
|
|
||||||
Map.get(state.instmap, inst) != nil and state.instmap[inst].has_sent_accept ->
|
Map.get(state.instmap, inst) != nil and state.instmap[inst].has_sent_accept ->
|
||||||
state
|
state
|
||||||
|
|
||||||
@ -315,6 +341,7 @@ defmodule Paxos do
|
|||||||
| prepared_values: [],
|
| prepared_values: [],
|
||||||
accepted: 0,
|
accepted: 0,
|
||||||
ballot_value: nil,
|
ballot_value: nil,
|
||||||
|
has_sent_prepare: true,
|
||||||
has_sent_accept: false
|
has_sent_accept: false
|
||||||
} end)
|
} end)
|
||||||
end
|
end
|
||||||
@ -330,10 +357,13 @@ defmodule Paxos do
|
|||||||
not state.instmap[inst].has_sent_accept do
|
not state.instmap[inst].has_sent_accept do
|
||||||
{_, a_val} =
|
{_, a_val} =
|
||||||
Enum.reduce(state.instmap[inst].prepared_values, {0, nil}, fn {bal, val},
|
Enum.reduce(state.instmap[inst].prepared_values, {0, nil}, fn {bal, val},
|
||||||
{a_bal, a_val} ->
|
{acc_bal, acc_val} ->
|
||||||
if a_bal > bal do
|
cond do
|
||||||
{a_bal, a_val}
|
val == nil ->
|
||||||
else
|
{acc_bal, acc_val}
|
||||||
|
acc_bal > bal ->
|
||||||
|
{acc_bal, acc_val}
|
||||||
|
true ->
|
||||||
{bal, val}
|
{bal, val}
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
@ -22,42 +22,42 @@ test_suite = [
|
|||||||
# Use TestUtil.get_local_config(n) to generate a single-node configuration
|
# Use TestUtil.get_local_config(n) to generate a single-node configuration
|
||||||
# consisting of n processes, all running on the same node.
|
# consisting of n processes, all running on the same node.
|
||||||
|
|
||||||
# {&PaxosTest.run_simple/3, TestUtil.get_local_config(3), 10,
|
{&PaxosTest.run_simple/3, TestUtil.get_local_config(3), 10,
|
||||||
# "No failures, no concurrent ballots, 3 local procs"},
|
"No failures, no concurrent ballots, 3 local procs"},
|
||||||
# {&PaxosTest.run_simple/3, TestUtil.get_dist_config(host, 3), 10,
|
{&PaxosTest.run_simple/3, TestUtil.get_dist_config(host, 3), 10,
|
||||||
# "No failures, no concurrent ballots, 3 nodes"},
|
"No failures, no concurrent ballots, 3 nodes"},
|
||||||
# {&PaxosTest.run_simple/3, TestUtil.get_local_config(5), 10,
|
{&PaxosTest.run_simple/3, TestUtil.get_local_config(5), 10,
|
||||||
# "No failures, no concurrent ballots, 5 local procs"},
|
"No failures, no concurrent ballots, 5 local procs"},
|
||||||
# {&PaxosTest.run_simple_2/3, TestUtil.get_dist_config(host, 3), 10,
|
{&PaxosTest.run_simple_2/3, TestUtil.get_dist_config(host, 3), 10,
|
||||||
# "No failures, 2 concurrent ballots, 3 nodes"},
|
"No failures, 2 concurrent ballots, 3 nodes"},
|
||||||
# {&PaxosTest.run_simple_2/3, TestUtil.get_local_config(3), 10,
|
{&PaxosTest.run_simple_2/3, TestUtil.get_local_config(3), 10,
|
||||||
# "No failures, 2 concurrent ballots, 3 local procs"},
|
"No failures, 2 concurrent ballots, 3 local procs"},
|
||||||
# {&PaxosTest.run_simple_3/3, TestUtil.get_local_config(3), 10,
|
{&PaxosTest.run_simple_3/3, TestUtil.get_local_config(3), 10,
|
||||||
# "No failures, 2 concurrent instances, 3 local procs"},
|
"No failures, 2 concurrent instances, 3 local procs"},
|
||||||
# {&PaxosTest.run_simple_many_1/3, TestUtil.get_dist_config(host, 5), 10,
|
{&PaxosTest.run_simple_many_1/3, TestUtil.get_dist_config(host, 5), 10,
|
||||||
# "No failures, many concurrent ballots 1, 5 nodes"},
|
"No failures, many concurrent ballots 1, 5 nodes"},
|
||||||
# {&PaxosTest.run_simple_many_1/3, TestUtil.get_local_config(5), 10,
|
{&PaxosTest.run_simple_many_1/3, TestUtil.get_local_config(5), 10,
|
||||||
# "No failures, many concurrent ballots 1, 5 local procs"},
|
"No failures, many concurrent ballots 1, 5 local procs"},
|
||||||
# {&PaxosTest.run_simple_many_2/3, TestUtil.get_dist_config(host, 5), 10,
|
{&PaxosTest.run_simple_many_2/3, TestUtil.get_dist_config(host, 5), 10,
|
||||||
# "No failures, many concurrent ballots 2, 5 nodes"},
|
"No failures, many concurrent ballots 2, 5 nodes"},
|
||||||
# {&PaxosTest.run_simple_many_2/3, TestUtil.get_local_config(5), 10,
|
{&PaxosTest.run_simple_many_2/3, TestUtil.get_local_config(5), 10,
|
||||||
# "No failures, many concurrent ballots 2, 5 local procs"},
|
"No failures, many concurrent ballots 2, 5 local procs"},
|
||||||
# {&PaxosTest.run_non_leader_crash/3, TestUtil.get_dist_config(host, 3), 10,
|
{&PaxosTest.run_non_leader_crash/3, TestUtil.get_dist_config(host, 3), 10,
|
||||||
# "One non-leader crashes, no concurrent ballots, 3 nodes"},
|
"One non-leader crashes, no concurrent ballots, 3 nodes"},
|
||||||
# {&PaxosTest.run_non_leader_crash/3, TestUtil.get_local_config(3), 10,
|
{&PaxosTest.run_non_leader_crash/3, TestUtil.get_local_config(3), 10,
|
||||||
# "One non-leader crashes, no concurrent ballots, 3 local procs"},
|
"One non-leader crashes, no concurrent ballots, 3 local procs"},
|
||||||
# {&PaxosTest.run_minority_non_leader_crash/3, TestUtil.get_dist_config(host, 5), 10,
|
{&PaxosTest.run_minority_non_leader_crash/3, TestUtil.get_dist_config(host, 5), 10,
|
||||||
# "Minority non-leader crashes, no concurrent ballots"},
|
"Minority non-leader crashes, no concurrent ballots"},
|
||||||
# {&PaxosTest.run_minority_non_leader_crash/3, TestUtil.get_local_config(5), 10,
|
{&PaxosTest.run_minority_non_leader_crash/3, TestUtil.get_local_config(5), 10,
|
||||||
# "Minority non-leader crashes, no concurrent ballots"},
|
"Minority non-leader crashes, no concurrent ballots"},
|
||||||
# {&PaxosTest.run_leader_crash_simple/3, TestUtil.get_dist_config(host, 5), 10,
|
{&PaxosTest.run_leader_crash_simple/3, TestUtil.get_dist_config(host, 5), 10,
|
||||||
# "Leader crashes, no concurrent ballots, 5 nodes"},
|
"Leader crashes, no concurrent ballots, 5 nodes"},
|
||||||
# {&PaxosTest.run_leader_crash_simple/3, TestUtil.get_local_config(5), 10,
|
{&PaxosTest.run_leader_crash_simple/3, TestUtil.get_local_config(5), 10,
|
||||||
# "Leader crashes, no concurrent ballots, 5 local procs"},
|
"Leader crashes, no concurrent ballots, 5 local procs"},
|
||||||
# {&PaxosTest.run_leader_crash_simple_2/3, TestUtil.get_dist_config(host, 7), 10,
|
{&PaxosTest.run_leader_crash_simple_2/3, TestUtil.get_dist_config(host, 7), 10,
|
||||||
# "Leader and some non-leaders crash, no concurrent ballots, 7 nodes"},
|
"Leader and some non-leaders crash, no concurrent ballots, 7 nodes"},
|
||||||
# {&PaxosTest.run_leader_crash_simple_2/3, TestUtil.get_local_config(7), 10,
|
{&PaxosTest.run_leader_crash_simple_2/3, TestUtil.get_local_config(7), 10,
|
||||||
# "Leader and some non-leaders crash, no concurrent ballots, 7 local procs"},
|
"Leader and some non-leaders crash, no concurrent ballots, 7 local procs"},
|
||||||
{&PaxosTest.run_leader_crash_complex/3, TestUtil.get_dist_config(host, 11), 10,
|
{&PaxosTest.run_leader_crash_complex/3, TestUtil.get_dist_config(host, 11), 10,
|
||||||
"Cascading failures of leaders and non-leaders, 11 nodes"},
|
"Cascading failures of leaders and non-leaders, 11 nodes"},
|
||||||
{&PaxosTest.run_leader_crash_complex/3, TestUtil.get_local_config(11), 10,
|
{&PaxosTest.run_leader_crash_complex/3, TestUtil.get_local_config(11), 10,
|
||||||
@ -69,10 +69,10 @@ test_suite = [
|
|||||||
|
|
||||||
# Aditional Test functions
|
# Aditional Test functions
|
||||||
|
|
||||||
# {&PaxosTestAditional.run_leader_crash_simple_before_decision/3, TestUtil.get_dist_config(host, 5), 10,
|
{&PaxosTestAditional.run_leader_crash_simple_before_decision/3, TestUtil.get_dist_config(host, 5), 10,
|
||||||
# "Leader crashes right before decision, no concurrent ballots, 5 nodes"},
|
"Leader crashes right before decision, no concurrent ballots, 5 nodes"},
|
||||||
# {&PaxosTestAditional.run_leader_crash_simple_before_decision/3, TestUtil.get_local_config(5), 10,
|
{&PaxosTestAditional.run_leader_crash_simple_before_decision/3, TestUtil.get_local_config(5), 10,
|
||||||
# "Leader crashes right before decision, no concurrent ballots, 5 local procs"},
|
"Leader crashes right before decision, no concurrent ballots, 5 local procs"},
|
||||||
]
|
]
|
||||||
|
|
||||||
Node.stop()
|
Node.stop()
|
||||||
|
Reference in New Issue
Block a user