バックエンド アプリケーションを外部 Websocket に接続する方法として、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を満足させる方法について、誰かが私に提案を手伝ってくれますか?
ありがとう!