如何从Phoenix Controller中与Elixir Agent进行通信?

时间:2018-05-04 06:10:25

标签: elixir phoenix-framework

当语言的创造者回答你的问题时,很快就能学会一门语言!好吧,我的问题是 - 你如何在Phoenix控制器方法中与代理进行通信?我在hello_blockchain / monitor.ex中找到了这个:

defmodule HelloBlockchain.Monitor do
  def start_link do
    Agent.start_link(fn -> %{} end)
  end

  def put(pid, key, value) do
    Agent.update(pid, &Map.put(&1, key, value))
  end

  def get(pid, key) do
    Agent.get(pid, &Map.get(&1, key))
  end
end

在我的hello_blockchain_web / controllers / block_controller.ex中,我想在控制器动作(列表)中保存一个值,并在下次调用时以相同的动作检索它。但是我需要Agent的pid才能做到这一点。我似乎也需要保存它。或者我可以使用命名的代理。但我需要一种方法来保存这个名字。它看起来像一个Catch-22。我错过了什么?

1 个答案:

答案 0 :(得分:1)

Agent文档页面以您可能按原样使用的示例开头。基本上:在Elixir中,您希望使用命名的 GenServername而不是pid查找它们。

这种方法有许多优点,例如服务器重启时name不会更改,而pid则会更改。

所以,你要做到以下几点:

defmodule HelloBlockchain.Monitor do
  use Agent

  def start_link do
    # __MODULE__ here would be HelloBlockchain.Monitor
    Agent.start_link(fn -> %{} end, name: __MODULE__)
  end

  def put(key, value) do
    Agent.update(__MODULE__, &Map.put(&1, key, value))
  end

  def get(key) do
    Agent.get(__MODULE__, &Map.get(&1, key))
  end
end

你们都准备好了; Agent.get(HelloBlockchain.Monitor, :foo)可以在任何地方使用(假设Agent确实已经开始并受到监督。)

显然,您不需要保存名称,只需提供预定义且已知的名称即可。 Elixir中的常用方法是使用此代理嵌套在其中的模块的名称。