2017-03-01 55 views
0

我有一个聊天应用程序,双方在进入聊天之前必须按“接受”。序列如下:Elixir + Phoenix:如何将代理商作为商店使用?

  1. 甲方加入该渠道。 Agentstart_link与派对 A的电子邮件地址作为密钥
  2. 乙方加入渠道。 Agentstart_link与乙方的电子邮件地址作为密钥
  3. 甲方 按接受。若B还没有接受(代理,Agent将存储Party A's email -> Party B's email -> true,否则将消息发送到 A方也接受乙方。
  4. 乙方印刷机接受。 如果A还没有接受,Agent将存储Party A's email -> Party B's email -> true ,否则将消息发送给甲方乙方 也接受了。

我遇到一个错误,现在它似乎并不像

2017-03-01T14:02:40.434791+00:00 app[web.1]: 14:02:40.433 [error] GenServer #PID<0.1743.0> terminating 
2017-03-01T14:02:40.434793+00:00 app[web.1]: ** (stop) exited in: GenServer.call(:"[email protected]", {:get, #Function<1.108716101/1 in VideoChat.CallChannel.handle_in/3>}, 5000) 
2017-03-01T14:02:40.434794+00:00 app[web.1]:  ** (EXIT) no process 
2017-03-01T14:02:40.434795+00:00 app[web.1]:  (elixir) lib/gen_server.ex:596: GenServer.call/3 
2017-03-01T14:02:40.434795+00:00 app[web.1]:  (video_chat) web/channels/call_channel.ex:152: VideoChat.CallChannel.handle_in/3 
2017-03-01T14:02:40.434796+00:00 app[web.1]:  (phoenix) lib/phoenix/channel/server.ex:226: anonymous fn/4 in Phoenix.Channel.Server.handle_info/2 
2017-03-01T14:02:40.434797+00:00 app[web.1]:  (stdlib) gen_server.erl:615: :gen_server.try_dispatch/4 
2017-03-01T14:02:40.434798+00:00 app[web.1]:  (stdlib) gen_server.erl:681: :gen_server.handle_msg/5 
2017-03-01T14:02:40.434798+00:00 app[web.1]:  (stdlib) proc_lib.erl:240: :proc_lib.init_p_do_apply/3 

这是我的频道:

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. this is line 152 
    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 

它似乎没有打破,当我在控制台中运行测试线:

iex(20)> Agent.start_link(fn -> %{} end, name: :"blah") 
{:ok, #PID<0.365.0>} 
iex(21)> Agent.get(:"blah", &(Map.get(&1, "sdfs"))) 
nil 

我只是用Agent不正确?

+0

您也可能应该修改标题,因为'Agent'只能用作商店。现在这听起来有点同义反应。 – mudasobwa

回答

1

这是一个失败的行:

Agent.get(:"#{matched_client_email}" ...) 

这是因为这Agent不一定开始。您在您的测试检查所不同的是,复制的行为,你应该:

iex(20)> Agent.start_link(fn -> %{} end, name: :"blah") 
{:ok, #PID<0.365.0>} 
iex(21)> Agent.get(:"foo", &(Map.get(&1, "sdfs"))) # NOTE :foo 

一个可以明确检查目标Agent已经启动,或try/catchAgent.get

除此之外,你在没有被监督的情况下产生代理;当Agent出于某种原因而出现故障时可能会导致意外问题:它不会重新启动(保持关闭),您将遇到上述情况。

我个人会带着一个监督Agent去,把所有东西都用email作为关键。价值可能会像你需要的那样复杂,只需地图email%{}

+0

嗨!我将如何添加一位主管?对不起,我是新来的elixir – Edmund

+0

在['Application.start/2'](https://hexdocs.pm/elixir/Application.html#start/2)在您的应用程序的最顶层文件中,由phoenix ,添加一个'工作者'。里面有一些例子。 – mudasobwa

+0

你指的是哪个文件? – Edmund