【问题标题】:Where to put service/initialization code in an Elixir/Mix/Phoenix app?在 Elixir/Mix/Phoenix 应用程序中将服务/初始化代码放在哪里?
【发布时间】:2017-09-07 02:32:55
【问题描述】:

我有一个 Elixir/Mix 应用程序(也是 Phoenix,但里面也有很多非 Phoenix 的东西),我想知道在“启动”代码中放入什么最佳实践,比如动态添加子代码到主管,开火“我还活着!” 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

这似乎是错误的,但我不知道我应该把这段代码放在哪里。

【问题讨论】:

    标签: elixir phoenix-framework


    【解决方案1】:

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

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

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

    【讨论】:

    • 很高兴知道,尤其是关于将东西放入init 的说明。我仍然不清楚在start_linkinit 等等中我应该/不应该做什么。无论如何,我很高兴知道我在这里没有犯下可怕的罪行。
    • start_link 是“客户端”,init 是“服务器端”。因此,使用 init,您可以访问进程的内部结构以设置状态等。另外 - 浏览一下 GenServer/Supervisor 代码(以及底层的 Erlang 实现)。它不是超级复杂,可以让您深入了解幕后发生的事情:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-01
    • 2016-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多