我正在尝试将 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
关于elixir - Phoenix : How to supervise an Agent?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42544704/