simplified paxos functions
This commit is contained in:
123
lib/paxos.ex
123
lib/paxos.ex
@@ -26,32 +26,25 @@ defmodule Paxos do
|
||||
run(state)
|
||||
end
|
||||
|
||||
def add_inst_map(state, inst, value, pid_to_inform, action) do
|
||||
|
||||
IO.puts("#{state.name} SET BALLOT VALUE 3 nil")
|
||||
|
||||
instmap =
|
||||
Map.put(state.instmap, inst, %{
|
||||
value: value,
|
||||
ballot: 0,
|
||||
ballot_value: nil,
|
||||
prepared_values: [],
|
||||
accepted: 0,
|
||||
accepted_ballot: nil,
|
||||
accepted_value: nil,
|
||||
pid_to_inform: pid_to_inform,
|
||||
has_sent_accept: false,
|
||||
action: action,
|
||||
})
|
||||
|
||||
%{state | instmap: instmap}
|
||||
end
|
||||
|
||||
def has_or_create(state, inst) do
|
||||
def has_or_create(state, inst, value \\ nil, pid_to_inform \\ nil, action \\ nil) do
|
||||
if Map.has_key?(state.instmap, inst) do
|
||||
state
|
||||
else
|
||||
add_inst_map(state, inst, nil, nil, nil)
|
||||
instmap =
|
||||
Map.put(state.instmap, inst, %{
|
||||
value: value,
|
||||
ballot: 0,
|
||||
ballot_value: nil,
|
||||
prepared_values: [],
|
||||
accepted: 0,
|
||||
accepted_ballot: nil,
|
||||
accepted_value: nil,
|
||||
pid_to_inform: pid_to_inform,
|
||||
has_sent_accept: false,
|
||||
action: action,
|
||||
})
|
||||
|
||||
%{state | instmap: instmap}
|
||||
end
|
||||
end
|
||||
|
||||
@@ -81,7 +74,7 @@ defmodule Paxos do
|
||||
|
||||
not Map.has_key?(state.instmap, inst) ->
|
||||
EagerReliableBroadcast.broadcast(state.name, {:other_propose, inst, value})
|
||||
state = add_inst_map(state, inst, value, pid_to_inform, action)
|
||||
state = has_or_create(state, inst, value, pid_to_inform, action)
|
||||
Process.send_after(self(), {:timeout, inst}, t)
|
||||
prepare(state, inst)
|
||||
|
||||
@@ -90,12 +83,12 @@ defmodule Paxos do
|
||||
Process.send_after(self(), {:timeout, inst}, t)
|
||||
|
||||
prepare(
|
||||
set_instmap(state, inst, %{
|
||||
state.instmap[inst]
|
||||
set_instmap(state, inst, fn map -> %{
|
||||
map
|
||||
| value: value,
|
||||
pid_to_inform: pid_to_inform,
|
||||
action: action,
|
||||
}),
|
||||
} end),
|
||||
inst
|
||||
)
|
||||
|
||||
@@ -127,7 +120,6 @@ defmodule Paxos do
|
||||
state
|
||||
|
||||
not Map.has_key?(state.instmap, inst) ->
|
||||
IO.puts("I think that is the cause")
|
||||
state = has_or_create(state, inst)
|
||||
|
||||
Utils.unicast(
|
||||
@@ -136,10 +128,10 @@ defmodule Paxos do
|
||||
proc
|
||||
)
|
||||
|
||||
set_instmap(state, inst, %{
|
||||
state.instmap[inst]
|
||||
set_instmap(state, inst, fn map -> %{
|
||||
map
|
||||
| ballot: ballot
|
||||
})
|
||||
} end)
|
||||
|
||||
ballot > state.instmap[inst].ballot ->
|
||||
Utils.unicast(
|
||||
@@ -148,10 +140,10 @@ defmodule Paxos do
|
||||
proc
|
||||
)
|
||||
|
||||
set_instmap(state, inst, %{
|
||||
state.instmap[inst]
|
||||
set_instmap(state, inst, fn map -> %{
|
||||
map
|
||||
| ballot: ballot
|
||||
})
|
||||
} end)
|
||||
|
||||
true ->
|
||||
Utils.unicast({:nack, inst, ballot}, proc)
|
||||
@@ -177,9 +169,9 @@ defmodule Paxos do
|
||||
send(state.instmap[inst].pid_to_inform, {:abort, inst})
|
||||
end
|
||||
|
||||
set_instmap(state, inst, %{
|
||||
state.instmap[inst] | has_sent_accept: false
|
||||
})
|
||||
set_instmap(state, inst, fn map -> %{
|
||||
map | has_sent_accept: false
|
||||
} end)
|
||||
|
||||
true ->
|
||||
state
|
||||
@@ -196,13 +188,10 @@ defmodule Paxos do
|
||||
|
||||
ballot == state.instmap[inst].ballot ->
|
||||
state =
|
||||
set_instmap(state, inst, %{
|
||||
state.instmap[inst]
|
||||
| prepared_values:
|
||||
state.instmap[inst].prepared_values ++ [{accepted_ballot, accepted_value}]
|
||||
})
|
||||
|
||||
IO.puts("#{state.name} Try to run prepared")
|
||||
set_instmap(state, inst, fn map -> %{
|
||||
map
|
||||
| prepared_values: map.prepared_values ++ [{accepted_ballot, accepted_value}]
|
||||
} end)
|
||||
|
||||
prepared(state, inst)
|
||||
|
||||
@@ -228,12 +217,12 @@ defmodule Paxos do
|
||||
|
||||
Utils.unicast({:accepted, inst, ballot}, proc)
|
||||
|
||||
set_instmap(state, inst, %{
|
||||
state.instmap[inst]
|
||||
set_instmap(state, inst, fn map -> %{
|
||||
map
|
||||
| ballot: ballot,
|
||||
accepted_value: value,
|
||||
accepted_ballot: ballot
|
||||
})
|
||||
} end)
|
||||
else
|
||||
IO.puts("#{state.name} -> #{proc} nack")
|
||||
Utils.unicast({:nack, inst, ballot}, proc)
|
||||
@@ -249,10 +238,10 @@ defmodule Paxos do
|
||||
else
|
||||
if state.leader == state.name and state.instmap[inst].ballot == ballot do
|
||||
accepted(
|
||||
set_instmap(state, inst, %{
|
||||
state.instmap[inst]
|
||||
| accepted: state.instmap[inst].accepted + 1
|
||||
}),
|
||||
set_instmap(state, inst, fn map -> %{
|
||||
map
|
||||
| accepted: map.accepted + 1
|
||||
} end),
|
||||
inst
|
||||
)
|
||||
else
|
||||
@@ -297,8 +286,8 @@ defmodule Paxos do
|
||||
)
|
||||
end
|
||||
|
||||
def set_instmap(state, inst, instmap) do
|
||||
new_instmap = Map.put(state.instmap, inst, instmap)
|
||||
def set_instmap(state, inst, set_instmap) do
|
||||
new_instmap = Map.put(state.instmap, inst, set_instmap.(state.instmap[inst]))
|
||||
%{state | instmap: new_instmap}
|
||||
end
|
||||
|
||||
@@ -321,14 +310,13 @@ defmodule Paxos do
|
||||
IO.puts("#{state.name} sending all prepare #{inst} #{ballot}")
|
||||
EagerReliableBroadcast.broadcast(state.name, {:prepare, state.name, inst, ballot})
|
||||
|
||||
IO.puts("#{state.name} SET BALLOT VALUE 2 nil")
|
||||
set_instmap(state, inst, %{
|
||||
state.instmap[inst]
|
||||
set_instmap(state, inst, fn map -> %{
|
||||
map
|
||||
| prepared_values: [],
|
||||
accepted: 0,
|
||||
ballot_value: nil,
|
||||
has_sent_accept: false
|
||||
})
|
||||
} end)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -338,7 +326,6 @@ defmodule Paxos do
|
||||
def prepared(state, _) when state.leader != state.name, do: state
|
||||
|
||||
def prepared(state, inst) do
|
||||
IO.puts("#{state.name} #{length(state.processes)} #{length(state.instmap[inst].prepared_values)} #{state.instmap[inst].has_sent_accept}")
|
||||
if length(state.instmap[inst].prepared_values) >= floor(length(state.processes) / 2) + 1 and
|
||||
not state.instmap[inst].has_sent_accept do
|
||||
{_, a_val} =
|
||||
@@ -367,13 +354,11 @@ defmodule Paxos do
|
||||
{:accept, inst, state.instmap[inst].ballot, a_val}
|
||||
)
|
||||
|
||||
IO.puts("#{state.name} SET BALLOT VALUE #{inspect(a_val)}")
|
||||
|
||||
set_instmap(state, inst, %{
|
||||
state.instmap[inst]
|
||||
set_instmap(state, inst, fn map -> %{
|
||||
map
|
||||
| ballot_value: a_val,
|
||||
has_sent_accept: true
|
||||
})
|
||||
} end)
|
||||
else
|
||||
state
|
||||
end
|
||||
@@ -412,22 +397,12 @@ defmodule Paxos do
|
||||
end
|
||||
end
|
||||
|
||||
def propose_action(pid, inst, value, t, action) do
|
||||
# Utils.unicast({:propose, value}, name)
|
||||
|
||||
def propose(pid, inst, value, t, action \\ nil) do
|
||||
send(pid, {:propose, inst, value, t, self(), action})
|
||||
|
||||
propose_loop(inst)
|
||||
end
|
||||
|
||||
def propose(pid, inst, value, t) do
|
||||
# Utils.unicast({:propose, value}, name)
|
||||
|
||||
send(pid, {:propose, inst, value, t, self(), nil})
|
||||
|
||||
propose_loop(inst)
|
||||
end
|
||||
|
||||
def propose_loop(inInst) do
|
||||
receive do
|
||||
{:timeout, inst} ->
|
||||
|
||||
Reference in New Issue
Block a user