将CLI args传递给`--sup`生成的应用程序

时间:2018-03-11 05:17:42

标签: elixir

我正在尝试使用--sup生成的应用程序,它们是如何实现的 开始以及如何传递CLI参数。

我使用mix new --module MyApp --sup myapp生成应用程序。在编译之前lib/myapp/application.ex被修改为

defmodule MyApp.Application do
  @moduledoc false
  use Application
  require Logger

  def start(type, args) do
    Logger.debug("[#{inspect self()}]:MyApp.Application.start(type=#{inspect type}, args=#{inspect args})")
    children = []
    opts = [strategy: :one_for_one, name: MyApp.Supervisor]
    Supervisor.start_link(children, opts)
  end
end

主要添加日志行,以便人们可以看到传递的内容 周围。

使用iex -S mix运行程序主要提供以下输出:

06:55:18.562 [debug] [#PID<0.111.0>]:MyApp.Application.start(type=:normal, args=[])

验证args收到的start是否来自 mix.exs,我使用application修改了mod: {MyApp.Application, [1, :two]}函数。执行收益率:

07:05:41.629 [debug] [#PID<0.143.0>]:MyApp.Application.start(type=:normal, args=[1, :two])

正如所料。

我的第一个问题是:应用程序的类型(第一个 start回调的参数报告为:normal而{。}} Application行为的文档仅定义了三种类型 :permanent:transient:temporary。我在这里想念什么?

第二个问题是:如何制作自包含的可执行文件 并从命令行调度参数。

自包含的可执行文件是使用escript创建的,对吗?我加 escript: [main_module: MyApp]行中的projectmix.exs并向main(args)模块添加了MyApp函数:

defmodule MyApp do
  require Logger

  def main(args) do
    Logger.debug("[#{inspect self()}]:MyApp.main(args=#{inspect(args)}")
  end
end

执行mix escript.build && ./myapp a b会生成两行日志:

07:53:22.973 [debug] [#PID<0.77.0>]:MyApp.Application.start(type=:normal, args=[1, :two])
07:53:22.980 [debug] [#PID<0.79.0>]:MyApp.main(args=["a", "b"]

MyApp.Application(如果我已实施,则为监督树 一个)以mix.exsmain中提供的参数开始 使用命令行参数调用mod: {MyApp.Application, [1, :two]}函数。除了, 两者都在不同的进程中运行......所以如何传递cli参数 监督树?

我正考虑在mix.esx中评论MyApp.main()行并修改MyApp.Application.start()以致电defmodule MyApp do require Logger require MyApp.Application def main(args) do Logger.debug("[#{inspect self()}]:MyApp.main(args=#{inspect(args)}") MyApp.Application.start(:normal, args) end end

08:08:16.865 [debug] [#PID<0.76.0>]:MyApp.main(args=["a", "b"]
08:08:16.868 [debug] [#PID<0.76.0>]:MyApp.Application.start(type=:normal, args=["a", "b"])

执行产生:

MyApp.Application.start

这似乎很好,但我想知道这是否是正确的方式,尤其是 如果运行时在调用之前有某种魔力 "sunday": [ "...", 7, 14, 21, 28 ] 可能不会在这里执行。

1 个答案:

答案 0 :(得分:1)

对于第一个问题,除非您正在构建分布式系统,否则通常会传递type :normal来启动主监督树。您通常会传递其他类型:permanent:transient:temporary来启动特定应用。 ElixirErlang个文档。

对于第二个问题,您可以通过start_link/2手动启动监督树,并将args传递给该功能,其中没有&#34;魔法&#34;通过手动启动Application或通过mix.exs(比手动更好)。唯一的问题是你的Application回调不应该执行任何代码操作,只能启动主管等...