erlang elixir otp

erlang - Obtener un proceso de hermanos en Elixir



otp (2)

Tengo un árbol de proceso de Elixir / Erlang:

parent (Supervisor) ├── child1 (GenServer) └── child2 (GenServer)

child1 (un cliente DB) tiene información que child2 necesita usar. ¿Cuál es una buena manera de pasar una referencia del proceso del Supervisor a child2 para que child2 siempre tenga una referencia válida para child1? ¿Solo necesito reestructurar mi aplicación para que child2 sea supervisado por child1?


No uso Elixir, pero utilizo Erlang, y creo que mi respuesta es válida en ambos casos.

Si sus procesos de tipo child1 son permanentes, y en número fijo, entonces la solución más simple es registrarlos (game_server, event_server, ...)

Pero si tienen vida transitoria, su número no es fijo, o existirán muchos procesos del mismo tipo (un proceso de jugador en un juego, por ejemplo). Sugiero usar otra organización:

  • El supervisor de nivel superior inicia 2 procesos, un servidor y un supervisor.
  • El servidor, al menos, mantendrá una lista de todos los procesos "hijo1" vivientes con algunas características (identificación de jugador ...) que permiten acceder a ellos. En general, también usará el proceso de supervisor para iniciar, matar ... los procesos "hijo1".
  • El supervisor es una fábrica simple que creará y supervisará el "niño1", utilizando una estrategia simple_one_for_one.

    parent (Supervisor) ├── child2 (GenServer) └── Client_supervisor(Supervisor) ├── Client_server(registered GenServer) └── Client_factory(registered Supervisor) ├── Child1(GenServer) ├── Child1''(GenServer) └── ...


La forma más simple sería probablemente que child1 y child1 se registraran bajo alias locales. Puede hacerlo al iniciar su GenServer al pasar la opción de name :

defmodule Child1 do use GenServer def start_link do GenServer.start_link(__MODULE__, [], name: __MODULE__) end end

En este caso, un proceso respaldado por el módulo Child1 se registrará localmente con un alias Child1 . Luego, si desea enviar mensajes, puede usar ese alias en lugar de un PID .

defmodule Child1 do # ... def get_data do GenServer.call(__MODULE__, :get_data) end def handle_call(:get_data, _from, state) do {:reply, extract_data_from_state(state), state} end end

Si desea una solución más compleja donde, por ejemplo, se pueden registrar muchos procesos diferentes del mismo tipo, eche un vistazo a la biblioteca de gproc