【发布时间】: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