This commit is contained in:
parent
05c09d10f3
commit
d5383e67b2
31
lib/paxos.ex
31
lib/paxos.ex
@ -168,7 +168,7 @@ defmodule Paxos do
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Guarantees that a specific state exists for a specific instance
|
# Guarantees that a specific state exists for a specific instance
|
||||||
defp has_or_create(state, inst, value \\ nil, pid_to_inform \\ nil, action \\ nil) do
|
defp has_or_create(state, inst, value \\ nil, pid_to_inform \\ nil) do
|
||||||
or_state state.instmap[inst] == nil do
|
or_state state.instmap[inst] == nil do
|
||||||
instmap =
|
instmap =
|
||||||
Map.put(state.instmap, inst, %{
|
Map.put(state.instmap, inst, %{
|
||||||
@ -183,7 +183,6 @@ defmodule Paxos do
|
|||||||
accepted_value: nil,
|
accepted_value: nil,
|
||||||
pid_to_inform: pid_to_inform,
|
pid_to_inform: pid_to_inform,
|
||||||
has_sent_accept: false,
|
has_sent_accept: false,
|
||||||
action: action,
|
|
||||||
has_sent_prepare: false,
|
has_sent_prepare: false,
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -206,7 +205,7 @@ defmodule Paxos do
|
|||||||
# This is the run/recieve function
|
# This is the run/recieve function
|
||||||
# All the messages that are handled by this function are:
|
# All the messages that are handled by this function are:
|
||||||
# {:ele_trust, proc} ->
|
# {:ele_trust, proc} ->
|
||||||
# {:propose, inst, value, pid_to_inform, action} ->
|
# {:propose, inst, value, pid_to_inform} ->
|
||||||
# {:rb_deliver, proc, {:other_propose, inst, value}} ->
|
# {:rb_deliver, proc, {:other_propose, inst, value}} ->
|
||||||
# {:rb_deliver, proc, {:prepare, proc, inst, ballot}} ->
|
# {:rb_deliver, proc, {:prepare, proc, inst, ballot}} ->
|
||||||
# {:nack, inst, ballot} ->
|
# {:nack, inst, ballot} ->
|
||||||
@ -226,8 +225,8 @@ defmodule Paxos do
|
|||||||
end)
|
end)
|
||||||
|
|
||||||
# Handles a proposal message from the parent process
|
# Handles a proposal message from the parent process
|
||||||
{:propose, inst, value, pid_to_inform, action} ->
|
{:propose, inst, value, pid_to_inform} ->
|
||||||
log("#{state.name} - Propose #{inspect(inst)} with action #{inspect(action)}")
|
log("#{state.name} - Propose #{inspect(inst)}")
|
||||||
|
|
||||||
cond do
|
cond do
|
||||||
has_finished(state, inst, true) ->
|
has_finished(state, inst, true) ->
|
||||||
@ -235,19 +234,9 @@ defmodule Paxos do
|
|||||||
send(pid_to_inform, {:decision, inst, state.decided[inst]})
|
send(pid_to_inform, {:decision, inst, state.decided[inst]})
|
||||||
state
|
state
|
||||||
|
|
||||||
action == :increase_ballot_number ->
|
|
||||||
log("#{state.name} - Got request to increase ballot number for inst #{inst}")
|
|
||||||
state = has_or_create(state, inst)
|
|
||||||
|
|
||||||
set_instmap do
|
|
||||||
%{map| ballot: Ballot.inc(map.ballot)}
|
|
||||||
end
|
|
||||||
|
|
||||||
state
|
|
||||||
|
|
||||||
not Map.has_key?(state.instmap, inst) ->
|
not Map.has_key?(state.instmap, inst) ->
|
||||||
EagerReliableBroadcast.broadcast(state.name, {:other_propose, inst, value})
|
EagerReliableBroadcast.broadcast(state.name, {:other_propose, inst, value})
|
||||||
state = has_or_create(state, inst, value, pid_to_inform, action)
|
state = has_or_create(state, inst, value, pid_to_inform)
|
||||||
prepare(state, inst)
|
prepare(state, inst)
|
||||||
|
|
||||||
state.instmap[inst].value == nil ->
|
state.instmap[inst].value == nil ->
|
||||||
@ -257,7 +246,6 @@ defmodule Paxos do
|
|||||||
%{ map |
|
%{ map |
|
||||||
value: value,
|
value: value,
|
||||||
pid_to_inform: pid_to_inform,
|
pid_to_inform: pid_to_inform,
|
||||||
action: action,
|
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -553,11 +541,6 @@ defmodule Paxos do
|
|||||||
or_state state.instmap[inst].accepted >= floor(length(state.processes) / 2) + 1 do
|
or_state state.instmap[inst].accepted >= floor(length(state.processes) / 2) + 1 do
|
||||||
value = state.instmap[inst].ballot_value
|
value = state.instmap[inst].ballot_value
|
||||||
|
|
||||||
if state.instmap[inst].action == :kill_before_decision do
|
|
||||||
log("#{state.name} - Leader has action to die before decision #{inspect({:decide, inst, value})}")
|
|
||||||
Process.exit(self(), :kill)
|
|
||||||
end
|
|
||||||
|
|
||||||
EagerReliableBroadcast.broadcast(
|
EagerReliableBroadcast.broadcast(
|
||||||
state.name,
|
state.name,
|
||||||
{:decide, inst, value}
|
{:decide, inst, value}
|
||||||
@ -582,8 +565,8 @@ defmodule Paxos do
|
|||||||
@doc """
|
@doc """
|
||||||
Send the propose message to the paxos replica and waits for a response from the correct instance
|
Send the propose message to the paxos replica and waits for a response from the correct instance
|
||||||
"""
|
"""
|
||||||
def propose(pid, inst, value, t, action \\ nil) do
|
def propose(pid, inst, value, t) do
|
||||||
send(pid, {:propose, inst, value, self(), action})
|
send(pid, {:propose, inst, value, self()})
|
||||||
|
|
||||||
propose_loop(inst, t)
|
propose_loop(inst, t)
|
||||||
end
|
end
|
||||||
|
@ -66,25 +66,25 @@ 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"},
|
||||||
|
#
|
||||||
{&PaxosTestAditional.run_non_leader_send_propose_after_leader_elected/3, TestUtil.get_dist_config(host, 5), 10,
|
# {&PaxosTestAditional.run_non_leader_send_propose_after_leader_elected/3, TestUtil.get_dist_config(host, 5), 10,
|
||||||
"Non-Leader proposes after leader is elected, 5 nodes"},
|
# "Non-Leader proposes after leader is elected, 5 nodes"},
|
||||||
{&PaxosTestAditional.run_non_leader_send_propose_after_leader_elected/3, TestUtil.get_local_config(5), 10,
|
# {&PaxosTestAditional.run_non_leader_send_propose_after_leader_elected/3, TestUtil.get_local_config(5), 10,
|
||||||
"Non-Leader proposes after leader is elected, 5 local procs"},
|
# "Non-Leader proposes after leader is elected, 5 local procs"},
|
||||||
|
#
|
||||||
{&PaxosTestAditional.run_leader_should_nack_simple/3, TestUtil.get_dist_config(host, 5), 10,
|
# {&PaxosTestAditional.run_leader_should_nack_simple/3, TestUtil.get_dist_config(host, 5), 10,
|
||||||
"Leader should nack before decision and then come to decision, no concurrent ballots, 5 nodes"},
|
# "Leader should nack before decision and then come to decision, no concurrent ballots, 5 nodes"},
|
||||||
{&PaxosTestAditional.run_leader_should_nack_simple/3, TestUtil.get_local_config(5), 10,
|
# {&PaxosTestAditional.run_leader_should_nack_simple/3, TestUtil.get_local_config(5), 10,
|
||||||
"Leader should nack before decision and then come to decision, 5 local procs"},
|
# "Leader should nack before decision and then come to decision, 5 local procs"},
|
||||||
|
#
|
||||||
{&PaxosTestAditional.run_non_leader_should_nack_simple/3, TestUtil.get_dist_config(host, 5), 10,
|
# {&PaxosTestAditional.run_non_leader_should_nack_simple/3, TestUtil.get_dist_config(host, 5), 10,
|
||||||
"Non-Leader should nack before decision and then come to decision, no concurrent ballots, 5 nodes"},
|
# "Non-Leader should nack before decision and then come to decision, no concurrent ballots, 5 nodes"},
|
||||||
{&PaxosTestAditional.run_non_leader_should_nack_simple/3, TestUtil.get_local_config(5), 10,
|
# {&PaxosTestAditional.run_non_leader_should_nack_simple/3, TestUtil.get_local_config(5), 10,
|
||||||
"Non-Leader should nack before decision and then come to decision, 5 local procs"},
|
# "Non-Leader should nack before decision and then come to decision, 5 local procs"},
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user