stevegrossi / sengoku

An online Risk-like game built with Elixir and Phoenix LiveView
https://www.playsengoku.com/
60 stars 3 forks source link

Convert game actions from call to cast #2

Closed stevegrossi closed 7 years ago

stevegrossi commented 7 years ago

Before, we were only ever broadcasting state updates as a result of player actions:

def handle_in("action", action, socket) do
  game_id = socket.assigns[:game_id]
  player_id = socket.assigns[:player_id]
  action = atomize_keys(action)
  new_state = GameServer.action(game_id, player_id, action)

  broadcast socket, "update", new_state
  {:noreply, socket}
end

This is fine (if not ideal) in a game with only human players. But in preparation for supporting computer-controlled players, I'll need to update state as a result of server-initiated actions. The current approach cannot support this.

So instead of broadcasting new state synchronously in the channel in response to user-initiated actions, we'll make this asynchronous: user-initiated actions will cast to the server, and whenever the server has handled them, it will broadcast them back to the players. This opens the door for the server arbitrarily broadcasting new state for other reasons, such as server-initiated actions.

I should have done this from the start. With GenServers it's a good idea to avoid call (which blocks the sending process) and prefer cast (which doesn't). If the GameServer ever takes a while to respond, cast means it won't also make the channel process slow to respond as well.