pragmatic - elixir lang
¿Qué comportamiento de OTP debo usar para una repetición "sin fin" de tareas? (1)
Quiero ejecutar repetidamente la misma secuencia de operaciones una y otra vez junto a una aplicación Phoenix (sin bloquear toda la aplicación web si algo frena en el trabajador, por supuesto) y no sé realmente si debo usar un GenServer, el Elixir Tareas, un agente o algo completamente diferente que no he pensado hasta ahora.
Cuando inicio mi aplicación Phoenix, un trabajador también debería comenzar, que periódicamente extrae algunos valores de una conexión en serie, los transmite a través de un canal Phoenix, los recopila hasta que se alcanza @save_interval
y luego calcula la mediana, difunde esa mediana a través de una canal y lo escribe en un InfluxDB. En este momento tengo algo (tipo de trabajo) como este:
def do_your_thing(serial_pid) do
Stream.interval(@interval_live)
|> get_new_values_from_serial(serial_pid)
|> broadcast!("live-channel:#{@name}")
|> Enum.take(div(@interval_save, @interval_live))
|> calculate_medians()
|> broadcast!("update-channel:#{@name}")
|> write_to_database()
do_your_thing(serial_pid) # repeat
end
Estoy empezando a descubrir todas esas cosas de la PTA y espero que alguno de ustedes pueda ayudarme a encontrar la dirección correcta aquí.
Debe usar un GenServer que se envía a sí mismo después de x segundos (60 segundos en el ejemplo a continuación):
defmodule MyApp.Worker do
use GenServer
def start_link() do
GenServer.start_link(__MODULE__, [])
end
def init([]) do
schedule_work()
{:ok, []}
end
def handle_info(:work, state) do
state = do_work(state)
schedule_work()
{:noreply, state}
end
defp do_work(state) do
# Do your work here and return state
end
defp schedule_work do
Process.send_after(self(), :work, 60_000)
end
end