I got here as I was about to start a similar post in relation to a game I am working on (phoenix based). I am currently prototyping my application and the first thing I am working on is adjusting my players health over time. To keep my explanation simple, I will break my programming task into the following sentence.
"The longer they spend in the channel, the more their health is affected."
I guess in my case the GenServer process is the Channel and I am using socket.assigns to keep a reference to my player. My players parameters (e.g their Health) are modified over time. And their status is pushed back down the socket to my frontend.
Coming from an OO background, I was immediately breaking everything up into processes. And my first line of thinking is that I would need a GenServer (call it MyApp.Player module) to represent my player (and link this to the phoenix channel). Then I would need another GenServer (call it MyApp.HealthModifier) which is linked to the relevant MyApp.Player process. Then the MyApp.HealthModifier process could deteoriate my MyApp.Players health by sending messages back with the amount their Health should be decremented by.
After reading Sasa Juric’s article “to spawn or not to spawn” (great article title by the way) - I started going in a different direction. I am still not sure if its the right direction, but time will tell.
I have now started treating the phoenix channel as the only GenServer that I will need (at this point in my applications infancy) and keeping track of how long they have spent in the channel in a socket.assigns variable. Then when it comes time to push the players state back to the front end. I can “modify” my player by letting them know how long they have been in the channel for and doing the appropriate calculations and rebinding to my socket.assigns reference.
Which is completely different to how I was going to approach the problem.
My only concern is I am now looking at adding other “modifiers” to the Player… e.g. I might have an MyApp.ArmorModifier that will increase the players armor over time and taking my second approach I would be serializing all this code as I would call the MyApp.HealthModifier and then call the MyApp.ArmorModifier (all based on the time spent in the channel). In a nutshell, my Player has a map of Modifiers and currently iterate that map and apply them one by one.
I am starting to wonder if it would be better to have processes that independently report back to the player as to how much their Health or Armor should be affected (and other processes for other modifiers down the track).
Maybe its too early in my applications lifecycle to be considering this and I should just keep punching it out the way I am until I hit a bottle neck! But I am also concerned about what will happen if the channel process fails and how I would bring back my Player state… Whereas I might be able to control that better with individual processes.
Let me know if this would be better in another thread… this ended up being longer than I planned, but I feel it is related.