Я использую библиотеку elixir-socket как способ подключения к моему внутреннему приложению к внешней веб-розетке. Мне нужно, чтобы этот процесс был управляемым (перезапустите, если что-то не получится, откройте экспоненциально, если он не сможет подключиться и т.д.)
В настоящее время я создал управляющий процесс GenServer, который порождает циклический сокет через заданный промежуток времени (упрощенно ниже). У меня есть руководитель, управляющий процессом SocketManager
(и, следовательно, связанным Socket
):
socket_manager.ex
defmodule MyApp.SocketManager do
def init(_) do
Process.flag(:trap_exit, true)
state = %{socket: nil}
{:ok, state, {:continue, :init}}
end
def handle_continue(:init, state) do
Task.start_link(fn ->
Socket.connect!()
end)
{:noreply, state}
end
end
socket.ex
defmodule MyApp.Socket do
def connect! do
socket = Socket.Web.connect!("xx.xx.com", secure: true, path: "/api/xxx")
SocketManager.socket_connected(socket) # save the socket in the SocketManager state
listen(socket)
end
defp listen(socket) do
case socket |> Socket.Web.recv!() do
{:text, data} ->
# handle message
{:close, :abnormal, _} ->
Process.exit(self(), :kill)
{:pong, _} ->
nil
end
listen(socket)
end
end
Вышеописанное прекрасно работает, но я не уверен, что это лучший способ структурировать это. Из того, что я понимаю, Task
должен быть только для задач с определенной продолжительностью жизни, а не для вечного процесса. Кроме того, при запуске mix dialyzer
я получаю следующий выход (ссылаясь на строку Task.spawn_link
в SocketManager
):
lib/myapp/socket_manager.ex:40:no_return
The created fun has no local return.
Может ли кто-нибудь помочь мне с предложениями о том, как еще структурировать это и как я мог бы удовлетворить Dialyzer?
Спасибо!