Ep. 138 - Use Case for GenServer state
I just listed to Episode 138 and wanted to share one use case where I really love to keep state in a genserver. I wrote and maintain the gnat library which handles sending and receiving messages via the nats message broker. In that library I have a genserver that manages a TCP connection to the message broker and as I receive bytes from the broker it parses them. It also manages a list of subscriptions that we have open.
In this use-case, when a connection dies it is really useful to throw away all of the connection-specific state (ie active subscriptions, message counts, bytes that haven't been parsed yet, etc). I don't have to worry about starting up a new connection with partial state, or trying to recover state from a crashed connection.
This is a much nicer pattern than what I had to do in Ruby when I was working on a RabbitMQ library where I was keeping tracking of state in objects that were available across thread and having to manually cleanup that data when disconnections happened.
@mmmries is there a particular reason why you don't use a DynamicSupervisor and spin up a new GenServer to handle each specific subscription/recipient/client?
BTW, I checked out the source of your library and that's a really nice example of well-factored and commented code! 👍
@OldhamMade thanks for the kind words. I ended up keeping the subscription state in the connection GenServer because the server manages subscription information per connection. If my TCP connection dies and needs to get re-established, then I will also need to re-subscribe. So in my code I decided to leave it up the user whether they would want to start up one connection per subscription (failures and re-subscriptions could be handled individually) or to setup a single connection with many subscriptions.
I have started playing around with the idea of a higher-level supervisor with the ConsumerSupervisor which monitors a connection process and re-subscribes when that connection process dies. Not 100% sure if I like that pattern yet, but it has been working in production for a while now.