Elixir enables stateful web applications, is it wrong to think like this?

There are some very articulate thoughts about when it does and does not make sense to use processes to hold state above.

I have some intuition myself about this, mostly leading to using process state for ongoing interactions when the interaction model is time-bound and matches a single connexion or session. Those would be some types of games, web sessions, etc.

However I would be grateful if you could apply your opinion re. whether or not it’s a good idea to use process state to various examples just to make sure I understand what you mean. Especially if @peerreynders and @hubertlepicki could chime in, that would be very useful :slight_smile:

  • In his online Elixir course (non-free, Elixir for Programmers) Dave Thomas uses one stateful GenServer holding the state of a Hangman game (letters already guessed, game status, turns left, etc.) for each connected client.

  • Lance Halvorsen, in line with his book that got recommended on this forum on several occasions (Functional Web Development with Elixir, OTP, and Phoenix) presented his Elixir at a Walking Pace talk at ElixirConf US 2018. In it, he describes how he uses one process per item to be tracked in a wharehouse / shipping system, complete with on-demand cold start (read state from disk). Albeit he admits this is going to be hell to scale to a multi-node system in the talk and does not really give an applicable solution for this, he seems to see quite a few benefits in doing this in terms of architecture.

EDIT: There is a reference by @peerreynders to a thread on the PragProg forums that might address this at least partially (GenServer docs: “handle_cast … should be used sparingly” Why?) but those forums seem to be closed now and I could find no cache of this thread elsewhere.

  • On several occasions on this forum, it has been suggested that GenServers are a good fit for holding DDD-aggregate type state, my understanding being a GenServer per aggregate instance, similar to Lance Halvorsen’s example, and not simply a stateless implementation of business logic, for example Domain Driven design : Aggregate roots as Elixir Processes/GenServer.

On that last one, I’d especially would love to get feedback from @hubertlepicki, as you seem in agreement above with not using processes to hold state as some default model, but at the same time seemed to agree that using them to maintaing aggregates is fine. I might be seeing a contradiction that does not exist there, and would really like to hear it from the horse’s mouth :slight_smile:

All this I guess eventually boils down to the (already mentionned above) excellent To spawn, or not to spawn? by @sasajuric

To frame it in terms of that article, is using a GenServer per DDD aggregate not a pure “thought concern” (red flag reason for using a process to maintain his state) because its role is to serialize access to that aggregate, and thus is a legitimate concurrency unit?

2 Likes