在GenServer.start_link/3中使用{:via,module,term}注册名称有什么好处?

sbs*_*sbs 11 elixir erlang-otp gen-server erlang-supervisor

GenServer.start_link/3我可以使用原子在本地注册一个名称,用于这样的过程:

defmodule Worker do
  use GenServer

  def start_link do
    GenServer.start_link(__MODULE__, nil, name: :worker)
  end
end
Run Code Online (Sandbox Code Playgroud)

然后我可以开始一个主管来监督这个过程:

defmodule Boss do
  use Supervisor

  def init(_) do
    children = [worker(Worker, [])]
    supervise(children, strategy: :one_for_one)
  end
end
Run Code Online (Sandbox Code Playgroud)

现在我想让主管监督3个Worker进程,所以我需要为这3个进程提供唯一的名称,这样当supervisor重新启动进程时,它将始终使用相同的符号名称.

我可以简单地使用字符串插值作为唯一的Worker进程名称,如下所示:

defmodule Worker do
  use GenServer

  def start_link(id) do
    GenServer.start_link(__MODULE__, nil, name: :"worker_#{id}")
  end
end
Run Code Online (Sandbox Code Playgroud)

然后监督3个这样的过程:

defmodule Boss do
  use Supervisor

  def init(_) do
    children = for id <- 1..3 do
      worker(Worker, [id], id: id)
    end
    supervise(children, strategy: :one_for_one)
  end
end
Run Code Online (Sandbox Code Playgroud)

它像预期的那样工作.

在" 名称注册"部分的 GenServer文档中,它表示您也可以使用{:via, module, term}注册名称.

{:via,module,term} - GenServer注册了给定的机制和名称.:via选项需要一个导出register_name/2,unregister_name/1,whereis_name/1和send/2的模块.一个这样的例子是:全局模块,它使用这些函数来保存进程名称列表及其关联的pid,这些列表可以在Erlang节点网络中全局使用.

然而,为了使用:via选项,你必须执行,出口模块register_name/2,unregister_name/1,whereis_name/1send/2,这似乎很繁琐比较简单地使用字符串插值技术,如上图所示.

所以我的问题是:

  1. 使用{:via,module,term}注册名称而不仅仅是使用字符串插值有什么好处?
  2. 是否有使用:via选项注册名称的实用示例?

Cod*_*oll 5

主要示例是当您要使用非标准名称注册库时。以gproc库为例。它遵循使用的接口要求:via,因此对您的应用程序代码的入侵最少。此外,与标准名称注册系统相比,它还具有一些优点:

  1. 使用任何术语作为流程别名
  2. 在多个别名下注册进程
  3. 非唯一属性可以由许多过程QLC和匹配规范接口同时注册,以对字典进行有效查询
  4. 等待注册,让您等到进程自行注册
  5. 以原子方式将注册的名称和属性提供给另一个进程
  6. 计数器和聚合计数器,它们自动维护具有给定名称的所有计数器的总数
  7. 全局注册表,上述所有功能均应用于节点网络

Elixir的Registry模块是另一个需要via元组的示例。

tl; dr- :via是否允许您使用非标准的过程注册库。它们必须符合接口(非常类似于用Java实现接口),并且可能提供额外的功能。


Dav*_*ulc 2

使用:via元组可以让您很好地封装别名处理,并为您提供一个可以发现进程的固定点。此外,:via元组可以是任意复杂的,例如这样的元组{:my_worker, 1}通常比乱搞字符串操作更好。

(请注意,我正在学习 Elixir,所以不要相信我的话。此外,元:via组可能有更强/更好的论据。)