Cómo monitorizar procesos

Un monitor permite enlazar dos procesos, pero a diferencia de lo que ocurre con un enlace normal, cuando el proceso monitorizado caiga, el proceso que monitoriza recibe un mensaje con los detalles de la caída del proceso monitorizado, para detectar una situación de error en uno de estos procesos.

Monitores

En la lección anterior estudiamos el funcionamiento de los enlaces entre procesos, y cómo se pueden usar para que un error en un proceso afecte a toda la malla de procesos que estén enlazados al proceso inicial.

Sin embargo, por lo general esta no será la solución que querremos tomar cuando un proceso tenga errores. Lo que querremos es detectar ese error desde fuera para tomar una acción correctiva, y esto no lo podemos hacer con enlaces normales, sino con monitores.

Cuando creamos un monitor, lo que estamos haciendo es crear una conexión entre dos procesos. En este caso, la relación no es bidireccional, sino que hay un proceso monitorizado y un proceso que monitoriza.

Para usar monitor con un proceso ya existente, puedes usar la primitiva Process.monitor/1, que recibe como parámtro el PID del proceso a monitorizar. El proceso que llame a Process.monitor se convertirá en el proceso que monitoriza el proceso monitorizado en busca de caídas. Eso significa que si el proceso A hace Process.monitor(b), una caída del proceso B notificará al proceso A, pero una caída de A no monitorizará al proceso B.

La función Process.monitor devuelve una reference(), que es una referencia de monitor que podemos usar luego para descartar el monitor usando Process.demonitor/1, como cuento un poco más abajo.

Una diferencia significativa entre link y monitor es que mientras que un par de procesos A y B sólo pueden tener un único enlace, pueden existir múltiples monitores vigilando el mismo grafo de procesos, así que puedes llamar a Process.monitor(pid) varias veces y recibirás una referencia nueva en cada caso. Cada referencia volcará un mensaje en el proceso que monitoriza, así que recibirás varias veces un mensaje si el proceso monitorizado cae.

Tratamiento de errores cuando hay monitores

Cuando haya establecido un monitor por el que A supervisa el proceso B, si el proceso B cae, el proceso A recibirá en su cola de mensajes una tupla con la siguiente forma:

{:DOWN, reference, :process, pid, reason}

El primer y el tercer elemento de la tupla tienen siempre el mismo aspecto. El primer elemento de la tupla es siempre el átomo :DOWN, mientras que el tercer átomo de la tupla, en el caso de Elixir, siempre va a ser :process. En cuanto a los elementos 2, 4 y 5:

  • El segundo elemento de la tupla, reference, es la referencia de monitor que previamente fue devuelta por Process.monitor.
  • El cuarto elemento de la tupla, pid, es el PID del proceso monitorizado, que es al que le pasamos como parámetro a Process.monitor.
  • El quinto elemento representa la razón por la que se ha interrumpido la ejecución del proceso. Puede ser la razón del error o el código de estado general entregado a la primitiva exit/1 al detener el proceso.

Podríamos tratar el error con pattern matching. Por ejemplo, como parte de la recepción de un mensaje:

receive do
  {:ok, res} ->
    IO.puts("Este es un mensaje completamente normal")
  {:DOWN, _, :process, _, reason} ->
    IO.puts(:stderr, "Algo ha salido mal")
    IO.inspect(reason)
end

Cómo eliminar un monitor

Si necesitas retirar un monitor de funcionamiento, puedes llamar a Process.demonitor/1 pasándole como parámetro la referencia que previamente te devolvió Process.monitor/1. El tipo de datos es la referencia, no el PID.

Lista de reproducción
  1. 1
    Cómo crear procesos
    11 minutos
  2. 2
    Cómo pasar mensajes entre procesos
    13 minutos
  3. 3
    Diccionario de un proceso y mantener un estado
    15 minutos
  4. 4
    Cómo enlazar procesos para detectar fallos
    13 minutos
  5. 5
    Cómo monitorizar procesos
    10 minutos
  6. 6
    ¿Qué es un GenServer?
    15 minutos
  7. 7
    Cómo enviar mensajes con un GenServer
    19 minutos
  8. 8
    Control de errores y gestión de un GenServer
    19 minutos
  9. 9
    Cómo renombrar procesos
    11 minutos
  10. 10
    Cómo crear un Supervisor Tree
    17 minutos
  11. 11
    Estrategias para trabajar con Supervisor
    18 minutos
  12. 12
    Estrategias para crear un Supervisor
    11 minutos
  13. 13
    Resumen sobre procesos OTP
    12 minutos
  14. 14
    Cómo usar Application
    12 minutos
  15. 15
    Ejemplo de Application con hijos
    14 minutos