-1

I need to create processes runtime, to keep different states. I have a list of users in my :config, such as:

config :backend,
 users: [user1, user2, user3]

Is it possible to cycle through this list and create a supervisioned Agent or Genserver for each of them?

Onorio Catenacci
  • 14,928
  • 14
  • 81
  • 132
Razinar
  • 727
  • 3
  • 13
  • 21

1 Answers1

2

Assuming the code in confix.exs is correct

config :backend,
  users: ~w[user1 user2 user3]

to start supervised children dynamically you might use e. g. DynamicSupervisor.

In your static initialization code you start DynamicSupervisor without any children:

children = [
  ...,
  {DynamicSupervisor, strategy: :one_for_one, name: MyApp.DS}
]
Supervisor.start_link(children, strategy: :one_for_one)

and when you want to start children dynamically, you basically do:

users = Application.get_env(:backend, :users, [])
agents =
  Enum.map(users, fn user ->
    with {:ok, agent} <- DynamicSupervisor.start_child(MyApp.DS, {Agent, fn -> %{} end}) do
      Agent.update(agent, &Map.put(&1, :user, user))
    end
  end)
Aleksei Matiushkin
  • 119,336
  • 10
  • 100
  • 160
  • Thank you so much. Btw agents are terminated upon arithmetic exception, without restarting, like if they are not supervisioned. – Razinar Jul 26 '18 at 09:13
  • No way. I am positive that using the code above `DynamicSupervisor` restarts agents upon termination. – Aleksei Matiushkin Jul 26 '18 at 09:25
  • My bad, i looked at log again and i can see "Client #PID<0.299.0> is alive" after the previous one got terminated. Problem is that now i cannot access it again using agent ( from pattern matching {:ok, agent} when i started manually the previous one). I need to give those agents a name, but i need to access them with the same name if they are restarted – Razinar Jul 26 '18 at 09:43
  • This is out of the scope of this question. Give the agent the name, or use [`child_spec`](https://hexdocs.pm/elixir/master/Supervisor.html#module-child-specification) to look up the agent with [`DynamicSupervisor.which_children/1`](https://hexdocs.pm/elixir/master/DynamicSupervisor.html#which_children/1), there are tons of ways to refer the process by name rather than by `PID`. – Aleksei Matiushkin Jul 26 '18 at 09:57