This commit is contained in:
		
							parent
							
								
									47b02d37ec
								
							
						
					
					
						commit
						1d2db555be
					
				
							
								
								
									
										19
									
								
								lib/paxos.ex
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								lib/paxos.ex
									
									
									
									
									
								
							| @ -228,9 +228,7 @@ defmodule Paxos do | ||||
|           safecast(proc, {:prepared, inst, ballot, state.instmap[inst].accepted_ballot, state.instmap[inst].accepted_value}); | ||||
|            | ||||
|           set_instmap do  | ||||
|             %{ map | ||||
|               | ballot: ballot | ||||
|             }  | ||||
|             %{ map | ballot: ballot }  | ||||
|           end | ||||
| 
 | ||||
|         Ballot.compare(ballot, &>/2, state.instmap[inst].ballot) -> | ||||
| @ -240,9 +238,7 @@ defmodule Paxos do | ||||
|           ) | ||||
| 
 | ||||
|           set_instmap do  | ||||
|             %{ map | ||||
|               | ballot: ballot | ||||
|             }  | ||||
|             %{ map | ballot: ballot }  | ||||
|           end | ||||
| 
 | ||||
|         true -> | ||||
| @ -257,7 +253,7 @@ defmodule Paxos do | ||||
|         has_finished(state, inst) -> | ||||
|           state | ||||
| 
 | ||||
|         state.leader == state.name and Ballot.compare(state.instmap[inst].ballot, &==/2, ballot) -> | ||||
|         state.leader == state.name and 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 | ||||
| @ -300,10 +296,9 @@ defmodule Paxos do | ||||
|         has_finished(state, inst) -> | ||||
|           state | ||||
| 
 | ||||
|         Ballot.compare(ballot, &==/2, state.instmap[inst].ballot) -> | ||||
|         ballot == state.instmap[inst].ballot -> | ||||
|           set_instmap do | ||||
|             %{ | ||||
|               map | ||||
|             %{ map | ||||
|               | prepared_values: map.prepared_values ++ [{accepted_ballot, accepted_value}] | ||||
|             } | ||||
|           end | ||||
| @ -354,9 +349,7 @@ defmodule Paxos do | ||||
| 
 | ||||
|         state.leader == state.name and state.instmap[inst].ballot == ballot -> | ||||
|           set_instmap do  | ||||
|             %{ map |  | ||||
|               accepted: map.accepted + 1 | ||||
|             } | ||||
|             %{ map |  accepted: map.accepted + 1 } | ||||
|           end | ||||
| 
 | ||||
|           accepted( state, inst) | ||||
|  | ||||
							
								
								
									
										104
									
								
								lib/server.ex
									
									
									
									
									
								
							
							
						
						
									
										104
									
								
								lib/server.ex
									
									
									
									
									
								
							| @ -8,15 +8,16 @@ defmodule ServerMacros do | ||||
|     end | ||||
|     ast2 = quote do | ||||
|       value -> | ||||
|         Process.send_after(self(), value, 100) | ||||
|         unquote(function_name)(v) | ||||
|         log("Got unexpected value: #{inspect(value)}") | ||||
|         Process.send_after(self(), value, t + 2000) | ||||
|         unquote(function_name)(v, t) | ||||
|     end | ||||
| 
 | ||||
|     ast3 = ast1 ++ match_exp ++ ast2 | ||||
| 
 | ||||
|     if after_exp != nil do | ||||
|       quote do | ||||
|         def unquote(function_name)(v) do | ||||
|         def unquote(function_name)(v, t) do | ||||
|           var!(v) = v | ||||
|           unquote(process_exp) | ||||
|           receive do | ||||
| @ -28,11 +29,13 @@ defmodule ServerMacros do | ||||
|       end | ||||
|     else | ||||
|       quote do | ||||
|         def unquote(function_name)(v) do | ||||
|         def unquote(function_name)(v, t) do | ||||
|           var!(v) = v | ||||
|           unquote(process_exp) | ||||
|           receive do | ||||
|             unquote(ast3) | ||||
|           after | ||||
|             t -> :timeout | ||||
|           end | ||||
|         end | ||||
|       end | ||||
| @ -63,7 +66,6 @@ defmodule ServerMacros do | ||||
|     ast2 = quote do | ||||
|       {:decision, v} -> | ||||
|         var!(state) = apply_game(var!(state), v) | ||||
|         var!(res) = v | ||||
|         unquote(recal_do) | ||||
| 
 | ||||
|       v -> | ||||
| @ -88,7 +90,7 @@ defmodule Server do | ||||
|   require Utils | ||||
|   import Utils | ||||
| 
 | ||||
|   create_log 2 | ||||
|   create_log 3 | ||||
| 
 | ||||
|   def start(name, participants) do | ||||
|     log("starting server") | ||||
| @ -115,39 +117,74 @@ defmodule Server do | ||||
|       {state, game_id} = try_to_create_game(state, participants) | ||||
|       safecast(pid_to_inform, {:start_game_ans, game_id}) | ||||
|       state | ||||
| 
 | ||||
|     {:get_game_state, game_id, pid_to_inform} -> | ||||
|       get_game_state(state, game_id, pid_to_inform) | ||||
|   end | ||||
| 
 | ||||
|   def get_game_state(state, game_id, pid_to_inform, repeat \\ false) do | ||||
|     cond do  | ||||
|       state.games[game_id] == :not_playing_in_game -> | ||||
|         safecast(pid_to_inform, {:game_state, game_id, :not_playing}) | ||||
|         state | ||||
| 
 | ||||
|       state.games[game_id] == nil -> | ||||
|         if repeat do | ||||
|           safecast(pid_to_inform, {:game_state, game_id, :game_does_not_exist}) | ||||
|           state | ||||
|         else | ||||
|           state = qurey_status(state) | ||||
|           get_game_state(state, game_id, pid_to_inform, true) | ||||
|         end | ||||
| 
 | ||||
|       true -> | ||||
|         state = qurey_status(state) | ||||
|         safecast(pid_to_inform, {:game_state, game_id, state.games[game_id].game_state, state.games[game_id].hand}) | ||||
|         state | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
| 
 | ||||
|   def try_to_create_game(state, participants) do | ||||
|     game_ids = Map.keys(state.games) | ||||
|     latest = Enum.at(Enum.sort(game_ids), length(game_ids) - 1) | ||||
|     log("#{inspect(latest)}") | ||||
|     new_game_id = if latest do latest else 0 end + 1 | ||||
|     log("#{inspect(new_game_id)}") | ||||
| 
 | ||||
|     # TODO: randomize game state | ||||
|     new_game_state = [1, 1] | ||||
|     # TODO: randomize Initial hand value | ||||
|     hand = Enum.reduce(participants, %{}, fn p, acc -> Map.put(acc, p, 1) end) | ||||
| 
 | ||||
|     res = nil | ||||
| 
 | ||||
|     try_propose {:start_game, new_game_id, participants, new_game_state, hand} | ||||
|     do | ||||
|       {:decision, {:start_game, ^new_game_id, ^participants, ^new_game_state, ^hand}} -> | ||||
|         state = apply_game(state, {:start_game, new_game_id, participants, new_game_state, hand}) | ||||
|         {state, new_game_id} | ||||
|     else | ||||
|       log("HERE #{inspect(res)}") | ||||
|       try_to_create_game(state, participants) | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|   # | ||||
|   # Utils | ||||
|   # | ||||
|    | ||||
|   def qurey_status(state) do | ||||
|     v = Paxos.get_decision(state.paxos, state.instance, 100) | ||||
|     or_state v != nil do | ||||
|       state = apply_game(state, v) | ||||
|       qurey_status(state) | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|   # | ||||
|   # Apply Game States | ||||
|   # | ||||
| 
 | ||||
|   def apply_game(state, {:start_game, game_id, participants, new_game_state, hand}) do | ||||
|     if state.name in participants do | ||||
|     cond do | ||||
|       state.games[game_id] -> | ||||
|         raise :game_already_exists | ||||
|       state.name in participants -> | ||||
|         %{state |  | ||||
|           games: Map.put(state.games, game_id, %{ | ||||
|             game_state: new_game_state, | ||||
| @ -156,15 +193,15 @@ defmodule Server do | ||||
|           }), | ||||
|           instance: state.instance + 1 | ||||
|         } | ||||
|     else | ||||
|       true -> | ||||
|         %{state |  | ||||
|         games: Map.put(state.games, game_id, :not_playing_in_it), | ||||
|           games: Map.put(state.games, game_id, :not_playing_in_game), | ||||
|           instance: state.instance + 1, | ||||
|         } | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|   def apply_game(state, _), do: raise :do_not_know_how_to_apply_game_state | ||||
|   def apply_game(_, _), do: raise :do_not_know_how_to_apply_game_state | ||||
| 
 | ||||
|   ############ | ||||
|   # Interface  | ||||
| @ -174,28 +211,31 @@ defmodule Server do | ||||
|      {:start_game_ans, game_id} -> | ||||
|        log("Started a game #{game_id}") | ||||
|        {:start_game, game_id} | ||||
|   after | ||||
|     1000 -> :timeout | ||||
|   end | ||||
| 
 | ||||
|   def start_game_loop() do | ||||
|     receive do | ||||
|      {:start_game_ans, game_id} -> | ||||
|        log("Started a game #{game_id}") | ||||
|        {:start_game, game_id} | ||||
|     v -> | ||||
|       Process.send_after(self(), v, 1000) | ||||
|       start_game_loop() | ||||
|     after | ||||
|       1000 -> :timeout | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|   def start_game(name, participants) do | ||||
|     safecast(name, {:start_game, participants, self()}) | ||||
|     start_game_loop(nil) | ||||
|     start_game_loop(nil, 1000) | ||||
|   end | ||||
| 
 | ||||
|   create_loop :get_game_state do | ||||
|     {:game_state, ^v, :not_playing} -> | ||||
|       IO.puts("Not Playing in that game") | ||||
|       :not_playing | ||||
|     {:game_state, ^v, game_state, hand} -> | ||||
|       IO.puts("Got game state, #{inspect(game_state)}, hand: #{inspect(hand)}") | ||||
|       {game_state, hand} | ||||
|     {:game_state, ^v, :game_does_not_exist} -> | ||||
|       IO.puts("Got game does not exist") | ||||
|       nil | ||||
|   end | ||||
| 
 | ||||
|   def get_game_state(name, game_id) do | ||||
|     safecast(name, {:get_game_state, game_id, self()}) | ||||
|     get_game_state_loop(game_id, 1000) | ||||
|   end | ||||
| 
 | ||||
| 
 | ||||
|   ############ | ||||
|   # Debug  | ||||
|   ############ | ||||
|  | ||||
		Reference in New Issue
	
	Block a user