如何运行 Elixir 应用程序?

Posted

技术标签:

【中文标题】如何运行 Elixir 应用程序?【英文标题】:How to run an Elixir application? 【发布时间】:2015-08-21 15:48:11 【问题描述】:

运行 Elixir 应用程序的正确方法是什么?

我正在创建一个简单的项目:

mix new app

然后我可以做:

mix run

这基本上编译了我的应用程序一次。所以当我添加:

IO.puts "running"

lib/app.ex 我看到"running" 只是第一次,每个连续的run 除非有一些变化,否则什么都不做。对于生成的app.app,接下来我可以做什么?

我当然知道我能做到:

escript: [main_module: App]

mix.exs 中,提供def main(args): 然后:

mix escript.build
./app

但在我看来这有点麻烦。

还有类似的:

elixir lib/app.exs

但它显然不算mix.exs,这是我的app 中的依赖项所必需的。

【问题讨论】:

如果您想运行 Elixir 脚本(.exs 文件)但在您的混音应用程序上下文中执行此操作,您可以运行 mix run <script>。请参阅mix help run 了解更多信息。 【参考方案1】:

mix run 确实运行您的应用程序。只是当您简单地将IO.puts "something" 放入文件中时,该行仅在编译时评估,它在运行时什么也不做。如果您想在启动应用程序时启动某些内容,则需要在 mix.exs 中指定。

通常您需要一个***的Application 来开始使用。要实现这一点,请将 mod 选项添加到您的 mix.exs

def application do
  [
    # this is the name of any module implementing the Application behaviour
    mod: NewMix, [],
    applications: [:logger]
  ]
end

然后在该模块中,您需要实现一个将在应用程序启动时调用的回调:

defmodule NewMix do
  use Application

  def start(_type, _args) do
    IO.puts "starting"
    # some more stuff
  end
end

start 回调实际上应该设置您的***进程或监督树根,但在这种情况下,您会看到每次使用 mix run 时都会调用它,尽管随后会出现错误。

def start(_type, _args) do
  IO.puts "starting"
  Task.start(fn -> :timer.sleep(1000); IO.puts("done sleeping") end)
end

在这种情况下,我们在回调中启动了一个简单的进程,它只休眠一秒钟,然后输出一些内容 - 这足以满足 start 回调的 API,但我们看不到 "done sleeping"。这样做的原因是默认情况下mix run 将在回调完成执行后退出。为了避免这种情况发生,您需要使用 mix run --no-halt - 在这种情况下,VM 不会停止。

另一种启动应用程序的有用方法是iex -S mix - 这与mix run --no-halt 的行为方式相似,但也会打开一个iex shell,您可以在其中与您的代码和正在运行的应用程序进行交互。

【讨论】:

好吧,这几乎就是我需要的!还有一件事,当没有TaskAgentSupervisor 等时,你能解释一下这个returned a bad value: :ok 错误吗?这是如何工作的,为什么我们需要一个单独的过程?为什么我不能只运行一些脚本来执行我需要的任何内容? 应用回调必须返回一个监督树。如果您不返回一个,它将失败。事实上,我什至会将 Paweł 显示的最后一个表达式替换为:Supervisor.start_link [], strategy: :one_for_one。返回关闭的任务可能会导致应用程序在休眠后失败。 @squixy 此处概述了使用和定义应用程序的一些好处:***.com/questions/30422184/… 如果您正在构建任何类型的长时间运行的应用程序,您几乎总是需要Supervisor。我使用Task 只是为了拥有最小的正确程序,但正如 Jose 所提到的 - 你想在那里开始你的监督树。 很好的答案!一个问题。你写了 “只是当你把 IO.puts "something" 放在一个文件中时,该行只在编译时评估,它在运行时什么都不做。” 这似乎与我所看到的相对应但我不明白这个逻辑?为什么会这样?【参考方案2】:

您可以通过将Mix.Task 导入模块而不是mix run 来运行任务。

我认为this 是您要找的。​​p>

除此之外,您可以简单地运行mix 而不是mix <task.run> 来运行默认任务。只需将default_task: "bot.run" 添加到mix.exs 中的def project do [..] end 列表中。参考here。

【讨论】:

以上是关于如何运行 Elixir 应用程序?的主要内容,如果未能解决你的问题,请参考以下文章

将本地 Elixir/Erlang 连接到 Docker 容器内正在运行的应用程序

在 elixir 应用程序中访问项目版本

将 iex shell 附加到正在运行的 elixir 应用程序

对只运行一次的程序使用 elixir 应用程序

Elixir - 从命令行运行时记录器输出是彩色的,从 iex 运行时不是这样

如何使用elixir测量磁盘大小?