Customize GenServer Behavior
Learn to customize GenServer behavior and use process registration to name individual games.
We'll cover the following
Plan the next step
Spawning and initializing a new GenServer
process is a great start. However, the default callback implementations we get by using GenServer
don’t go very far.
In order to build real applications, we need to change the way GenServer
behaves to fit each application’s needs.
-
To do this, we’re going to follow the pattern we’ve used so far. First, write a client function that wraps a
GenServer
function. This, in turn, triggers a callback. We’ll define the new behavior in the callback. -
Each time we add a new public function, we build a new piece of the interface for the game. As we go along, we’ll expose more and more of the game’s behavior. This interface acts as a boundary between the rest of the system and the game. That makes it the right place to check any values passed into the public functions.
-
We’ll need to check some conditions in each callback before determining whether the action went as planned. At a minimum, we need to check the rules for each action. Additionally, we might have to check that coordinates and islands are valid or that a player has positioned all their islands.
-
We could do this with conditional logic, but that could easily turn into a mess. Instead, we rely on Elixir’s
with/1
special form. Thewith/1
form was designed to test multiple conditions in the same place without nested conditionals. -
Every time we use
with/1
, we employ the same three blocks. Thewith
block contains all the conditions we’re testing. Thedo
block is for the actions we take when all the conditions pass, and theelse
block is where we handle errors.
Besides starting a new game, there are four behaviors we need to define:
- Adding a second player
- Positioning islands
- Setting islands
- Guessing coordinates
We’ll handle them in the same order.
Get hands-on with 1200+ tech skills courses.