GenServer and Application

Learn how to implement a GenServer for the game logic.

GenServer

Definition

GenServer is an Elixir Behaviour that wraps its Erlang counterpart, :gen_server. The GenServer Behaviour automatically creates default implementations of the :gen_server callbacks so that we only write code specific to our GenServer. We’ll use the Elixir GenServer as we build our game server, which will spare us from writing a lot of boilerplate.

Job

The GenServer Behaviour processes provide most of what we want from services, and also address problems services create. They are separate Elixir processes that listen for and respond to messages from other processes. They can hold state and also take action in the system.

Because they are separate processes that share nothing with other processes, we get the isolation and encapsulation we’re looking for. We can spawn new processes to address scaling needs, and do it at a granular level.

Elixir applications that use GenServer processes are just normal Elixir applications. There’s no extra work necessary to set up a development environment. We won’t need any external means to allow a GenServer process to communicate with the rest of the application.

Testing and deployment

Testing works exactly the same as with any other Elixir app. There’s no need to mock another service because the application remains a single whole.

Deployments are the same as well. Whatever deployment strategy we currently use will work. Since the GenServer is integrated with the rest of the application, there’s no way to create a version mismatch.

We don’t need extra planning or work to ensure fault tolerance. GenServer processes can be supervised, so we naturally get a level of fault tolerance that’s very difficult to match in any other system.

Application

Elixir Application Behaviours take on the “Where to divide a monolith into services?” question. They are the intermediary organizing constructs that most languages lack.

Definition

Like GenServer, an Application is an Elixir Behaviour that wraps its OTP counterpart, :application. Application provides default implementations for :application callbacks.

We need to make an important distinction first. An Application is not what we usually think of as a complete software application. It’s closer to what we would call a library or a package in other ecosystems. They are a little different, though. Applications are supervised units of code that start and stop as a single entity.

Uses

We can use Applications as libraries or packages if we want, but they can also be integral, named, delineated parts of an application. They naturally define facets we can break an application apart by if our needs demand it.

Back when we generated our islands_engine project in Model Data and Behavior, we noted that Elixir generated it as an Application for us. That’s good news because we’ve been working with an Application all along without any extra effort.

We’ll see how an Application makes separating game logic from the web interface easy in Generate a New Web Interface with Phoenix. We’ll also see that Applications have a role to play in process supervision in Process Supervision for Recovery.

Get hands-on with 1400+ tech skills courses.