Continuously spawn GenServers without running out of names/atoms over time

Background
I was inspired by the this tic tac toe in live view article and thought it would be cool to build something like this.

As games need state, the most obvious solution (to me, maybe there are better solutions) is to use a GenServer for each game, with its life-time being bound to the game itself.

Problem

  • Each game uses the same GenServer Module
  • All processes need different names. Names are atoms.
  • Randomly generating names will lead to runtime generated atoms, and I would like to avoid that (although I guess it would never really be a problem, because the number of available atoms is most likely way higher than the number games that will ever be played :smiley:)

Possible Solution?
I thought a way could maybe be to simply set a hard limit to the number of games (e.g. 10k).
Then generate all the atoms (:game_1 to :game_10000) on startup.

On spawning a new GenServer, a name within the allowed range is picked at random.
If a process with this name exists, pick another name. Once no process has been found for a name, use this name to start a new server.

Players could then connect to the games with unique links that are translated via a Registry. Once the original process/game has been stopped, the invite link will be removed and is no longer valid, even if another game/GenServer with the same name is created.

This way, processes could be spawned continuously, as long as the maximum number of processes is not hit, while players/invites can still be unique.

Question
Do you see any pitfalls on my suggested solution?
Is there a common or better solution to this problem?
What would be your solution?

1 Like

Use Registry and :via tuples for naming instead of atoms. The key can be arbitrary terms then.

5 Likes

I would also leverage a Registry like @NobbZ mentioned as well as a dynamic supervisor to watch over these game processes. Usually named processes are for when you have a singleton process or just a handful of processes in a pool. Not for when the number of processes can be unbounded. With that said I would not lean on naming these processes using atoms. Use strings instead to denote the game instance and the Registry to look up the GenServer by that string identifier.

I actually have an article series on this exact architecture:

Hope that helps!

4 Likes

Great, thanks a lot!
Now that I read your answers, I think I actually read about this option somehow but guess I did not really understand what I was reading :sweat_smile:

1 Like

You can check for uniqueness in the list of active games maintained by a game registry. If response is false, generate a new game code. The following example generates 4 character game codes and ensures they are unique among active games.

https://github.com/nshafer/answercast_lv/blob/master/lib/answercast/util.ex

My example implementation also uses this method.

https://shiptoaster.com

1 Like

Great ressource, thank you so much!