在Elixir/Mix/Phoenix应用程序中放置服务/初始化代码的位置?

Mic*_*cah 8 elixir phoenix-framework

我有一个Elixir/Mix应用程序(也有凤凰城,但也有很多非凤凰城的东西),我想知道什么是最好的做法,用于放入"启动"代码,例如动态地将孩子添加到主管,解雇关闭"我还活着!" ping或其他你希望在启动后立即发生的事情.

一个显而易见的地方是Application文件,但预期的返回是从中返回的Supervisor.start_link(children, opts).所以,例如,在Phoenix应用程序中,我可以这样做:

defmodule MyApp do
  use Application

  def start(_type, _args) do
    import Supervisor.Spec

    children = [
      supervisor(MyApp.Repo, []),
      supervisor(MyApp.Endpoint, []),
      supervisor(MyApp.DynamicSupervisorThingy, [])
    ]
    opts = [strategy: :one_for_one, name: MyApp.Supervisor]
    start_val = Supervisor.start_link(children, opts)



    # --- Put things right here that I want to start ----
    MyApp.DynamicSupervisorThingy.add_children_dynamically()
    MyApp.SomeModule.do_some_thingy()
    MyApp.OtherModule.send_some_pings()
    if MIX_ENV == :prod do
      MyApp.YetAnother.prod_stuff_i_dont_want_in_dev()
    end


    start_val
  end
end
Run Code Online (Sandbox Code Playgroud)

这似乎是错的,但我无法弄清楚我应该把这段代码放在哪里.

cde*_*oot 3

完全没问题。你的 Phoenix 应用程序只是一个 OTP 应用程序,你可以随心所欲地搬起石头砸自己的脚。Application.start只需要一个{:ok, pid}元组,它基本上是应用程序的顶级进程。

我通常首先放置我的自定义启动代码,然后设置主主管规范并启动该主管 - 请注意,如果您在启动的“动态主管”和添加的应用程序之间存在排序依赖关系,就像上面的情况一样,您可能会因为计时问题而失败 - 我会在其规范中正确配置该主管,以便它可以在init回调中执行操作,但我不知道您的代码或您的要求。

无论如何,Application.start只要您遵守合同,一切都是您的:-)