elixir - Phoenix : How to supervise an Agent?

标签 elixir phoenix-framework

我正在尝试将 Agent 用作商店。但是,我遇到的问题是我用来存储数据的 key 不存在。

这是我的 channel :

  def join("user_pool:" <> email, %{ "app" => app }, socket) do
    Logger.info "PRODUCTION user_pool email: #{email}, app: #{app}"
    socket = assign(socket, :email, email)
    socket = assign(socket, :app, app)

    Agent.start_link(fn -> %{} end, name: :"#{email}") # <---------------- should start link here
    {:ok, socket}
  end


  def handle_in("approve_match", %{ "matched_client_email" => matched_client_email }, socket) do
    Logger.info "approve_match"
    current_user_email = socket.assigns[:email]

    Agent.update :"#{current_user_email}", fn state ->
      Map.put(state, matched_client_email, true)
    end

    match_accepted = Agent.get(:"#{matched_client_email}", &(Map.get(&1, current_user_email))) # <----------- breaks here. says they matched_client_email key does not exist in Agent.
    Logger.info "#{matched_client_email} has approved #{current_user_email}: #{match_accepted}"
    case match_accepted do
      true ->
        VideoChat.Endpoint.broadcast(
          "user_pool:#{matched_client_email}",
          "match_accepted",
          %{ matched_client_email: socket.assigns[:email] }
        )
        {:noreply, socket}
      _ ->
        Logger.info "2nd person has yet to approve"
        {:noreply, socket}
    end
  end

有人建议我为此创建一个主管,但我不确定如何创建。我知道我必须在 lib/my_app.exs 中的注释行中添加一些内容,但我找不到什么。我也不是 100% 确定这会解决我的问题。

  def start(_type, _args) do
    import Supervisor.Spec

    # Define workers and child supervisors to be supervised
    children = [
      # Start the Ecto repository
      supervisor(VideoChat.Repo, []),
      # Start the endpoint when the application starts
      supervisor(VideoChat.Endpoint, []),
      # Start your own worker by calling: VideoChat.Worker.start_link(arg1, arg2, arg3)
      # worker(VideoChat.Worker, [arg1, arg2, arg3]),
    ]

    # See http://elixir-lang.org/docs/stable/elixir/Supervisor.html
    # for other strategies and supported options
    opts = [strategy: :one_for_one, name: VideoChat.Supervisor]
    Supervisor.start_link(children, opts)
  end

最佳答案

只是取消注释

# worker(VideoChat.Worker, [])

在那里传递适当的模块而不是 VideoChat.Worker。参数将传递给相应的 VideoChat.Worker.start_link 函数。一旦崩溃,这个特定的 Agent 将被重新启动。下面是一个人为的例子:

lib/my_app.ex

children = [
  # Start the Ecto repository
  supervisor(VideoChat.Repo, []),
  # Start the endpoint when the application starts
  supervisor(VideoChat.Endpoint, []),
  # start our own agent
  worker(VideoChat.Store, [])
]

lib/video_chat/store.ex

defmodule VideoChat.Store do
  @moduledoc "The store, based on `Agent`."

  def start_link do
    Agent.start_link(fn -> %{} end, name: __MODULE__)
  end

  @doc "Gets a value"
  @spec get(String.t) :: Map.t
  def get(key) do
    Agent.get(__MODULE__, &Map.get(&1, key))
  end

  @doc "Puts a value"
  @spec put(String.t, {String.t, any}) :: Map.t
  def put(key, {inner_key, inner_value}) do
    # more sophisticated implementation,
    # possibly based on `Agent.get_and_update/3`
  end
end

Agent.get_and_update/3 .

关于elixir - Phoenix : How to supervise an Agent?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42544704/

相关文章:

string - 如何在Elixir字符串中双引号嵌入?

testing - Phoenix API : How do I test a POST/create when I don't know the ID of the new resource?

elixir - 如何使用 Elixir Ecto 将字段绑定(bind)到具有不同名称的列

elixir - Keyword.Merge/3 函数中删除了键

postgresql - Phoenix Ecto Postgres 表未创建

elixir ecto naive_datetime 转换错误

elixir - 如何在长列表上使用 IO.inspect 而不对其进行修剪?

postgresql - 适配器 Ecto.Adapters.Postgres 未编译

elixir - Phoenix : foreign key not being inserted

iis - 在 Windows 上的 IIS 中运行 Phoenix 时内存泄漏/CPU 使用率持续居高不下