1

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

ありがとう!

4

1 に答える 1