Resumen de la clase:
Qué son los procesos
En elixir todo código se ejecuta en procesos. Los procesos están aislados unos de otros, se comunican pasándose mensajes y se pueden ejecutar de manera concurrente.
Los procesos son la base de la concurrencia en Elixir y para generar sistemas distribuidos y tolerantes a fallos. Son muy ligeros y se suelen ver miles de procesos en ejecución.
Para crear un proceso se usa el comando spawn. Eje:
spawn(fn -> 1 + 2 end)
Que devuelve un PID que corresponde al identificador del proceso que ejecutó esa función.
el PID se puede capturar en una variable, así:
pid = spawn(fn -> 1 + 2 end)
y con Process se puede averiguar si el proceso con ese pid está vivo:
self()
Process.alive?(pid)
Devuelve true o false
Con self() devuelve el pid del proceso actual:
self()
Process.alive?(self())
Pase de mensajes
Se usa send. Ej:
send(self(), {:hello, "World"})
el resultado se deposita en el mailbox del proceso actual.
Para recibir los mensajes se hace:
receive do
{:hello, msg} -> msg
{:world, _msg} -> "won't match"
end
La función recorrió el buzón de mensajes y extrajo el mensaje que coincidió con la primera opción.
Al realizar la prueba, se puede ver que la función send no bloquea el proceso y continua el flujo de ejecución.
El comando receive también se puede usar con un tiempo de espera, así:
receive do
{:hello, msg} -> msg
after
1_000 -> "Nothing after 1s"
end
En el siguiente ejemplo el mismo proceso se va a enviar un mensaje:
send(self(), {:hello, selft()})
receive do
{:hello, pid} -> "Got hello from #{inspect(pid)}"
end
La función inspect sirve para imprimir la representación en cadena o string de un proceso o variable.
La función flush() extrae los mensajes del buzón. Ej:
send(self(), :hello)
flush()
Cuando los procesos fallan, generan una excepción y esta excepción se puede enlazar, en cuyo caso la excepción se propaga. Ej:
self()
spawn(fn -> raise “oops” end)
# Aquí sigue teniendo el mismo pid
self()
# Se lanza un proceso enlazado
spawn_link(fn -> raise “oops” end)
self()
# El pid del proceso actual cambia porque el proceso más alto, recibió el error propagado (el que lo origina y el de la consola de iex) y reinicia los dos procesos.
Normalmente los procesos no suelen usarse de manera independiente, regularmente se usan con el módulo Task.