I then solved the problem by holding the state of the Map
in a GenServer
[...]
Generally, is this the right approach, or was this too much here?
It heavily depends on your goal. There are many different ways to store the state. Rebinding variables like:
m = Map.put(%{}, :a, 1)
#⇒ %{a: 1}
m = Map.put(m, :b, 2)
#⇒ %{a: 1, b: 2}
Does not store anything. It binds the local variable m
to RHO and as soon as the control flow leaves the scope, this variable becomes garbage collected. Whether you need the aforementioned map within a single scope, GenServer
(and other state holders) is an overkill.
OTOH, if you need to store the state for a long time and share it between different scopes (e. g. between different processes,) GenServer
is the simplest way to accomplish that. In Elixir we have Agent
module to decrease the boilerplate for GenServer
that is used as a simple in-memory storage, but my advice would be to always use GenServer
: sooner or later Agent
will become too tight for your purposes.
Also, one might use ets
module to keep in-memory key-value storage, shared between processes.
dets
is a way to store the state between process restarts.
And, finally, mnesia
is an OTP native approach to share the state between both restarts and different nodes (in distributed environment.)