【问题标题】:Prevent duplicate named processes防止重复的命名进程
【发布时间】:2017-02-10 10:38:11
【问题描述】:

我有一个 elixir (Phoenix) 应用程序,它会定期为用户检索分析数据。

我有一个AnalyticSupervisor 来监督AnalyticWorkers。

defmodule AnalyticsSupervisor do
  use Supervisor

  def start_link do
    Supervisor.start_link(__MODULE__, [], name: :analytics_supervisor)
  end

  def init(_) do
    children = [
      worker(AnalyticsWorker, [])
    ]

    supervise(children, strategy: :simple_one_for_one)
  end

  def start_worker(user) do
    Supervisor.start_child(:analytics_supervisor, [user])
  end
end

AnalyticWorker 使用gproc 作为进程注册表来创建动态进程名称并将分析调用排队。

defmodule AnalyticsWorker do
  use GenServer

  def start_link(user) do
    GenServer.start_link(__MODULE__, user, name: via_tuple(user))
  end

  defp via_tuple(user) do
    {:via, :gproc, {:n, :l, {:analytics_worker, user.id}}}
  end

  def init(user) do
    queue_analytic_call(user)
    {:ok, user}
  end

  def queue_analytic_call(user) do
    :timer.apply_after(50000, __MODULE__, :call_anlaytics, [user])
  end
end

AnaylticSupervisor 在我的 Phoenix 应用程序启动时启动,并将为任何现有用户排队分析调用。

问题是,如果我启动另一个 iex 会话,这也会启动主管和工作人员 - 我最终会为同一个工作创建多个进程。

我认为使用gproc 作为进程注册表,这是可以避免的——但是每个iex 会话都在创建它自己的进程注册表。

  • 如何确保进程是唯一的,无论它们是由 iex 会话还是我的 Phoneix 应用程序排队?

  • 有没有比我现在做的更好的方法来完成独特的计划作业?

【问题讨论】:

    标签: elixir phoenix-framework erlang-otp erlang-supervisor


    【解决方案1】:

    通过运行“另一个 iex 实例”,您基本上是在创建新的 erlang 节点,它对周围运行的其他节点一无所知。

    确保进程是唯一的,无论它们是由 iex 会话还是我的 Phoneix 应用程序排队,一个选项是附加随后启动的iex 给正在运行的那个。假设,原始进程开始于:

    #                           ⇓⇓⇓⇓⇓⇓⇓⇓⇓
    MIX_ENV=prod elixir --sname analytics -S mix run --no-halt
    

    iex附加到它使用:

    #       put resolvable host name here ⇓⇓⇓⇓⇓⇓⇓⇓⇓
    iex --sname console --remsh analytics@localhost
    

    由于第二个问题是 a) 同一 OP 中的第二个问题和 b) 高度基于意见,我建议您将您所拥有的内容与现有的实现进行比较(常见的方法是 使用Redis或喜欢以确保唯一性):

    另外,Task.Supervisor 可能满足您对零成本的要求。

    【讨论】:

    • 非常感谢,这完全有道理!我天真地假设进程 ID 将被共享。我可以在本地连接到同一个会话,但我目前在 heroku 上托管我的应用程序,这不允许 dynos 之间的通信。在 redis 中排队作业看起来是最好的选择。此外,看起来Task.Supervisor 会为我节省一些样板文件!
    猜你喜欢
    • 1970-01-01
    • 2014-02-04
    • 1970-01-01
    • 2014-05-03
    • 1970-01-01
    • 1970-01-01
    • 2017-04-14
    • 1970-01-01
    • 2020-02-13
    相关资源
    最近更新 更多