如何运行Elixir应用程序?


81

运行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显然不算在内,这对于my中的依赖项是必需的app


1
如果要运行Elixir脚本(.exs文件),但要在混合应用程序的上下文中运行,可以运行mix run <script>。请参阅mix help run以获取更多信息。
Michelle Tilley 2015年

Answers:


103

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但又打开了一个iexShell,您可以在其中与代码和正在运行的应用程序进行交互。


4
好吧,这几乎是我所需要的!还有一件事,你能解释一下这个returned a bad value: :ok时候有没有错误Task,或者Agent还是Supervisor等?它是如何工作的,为什么我们需要一个单独的流程?为什么我不能只运行一些执行我需要的脚本?
卡米尔·莱隆克

18
应用程序回调必须返回监管树。如果您不退货,它将失败。实际上,我什至将Paweł显示的最后一个表达式替换为:Supervisor.start_link [], strategy: :one_for_one。返回关闭的任务可能会导致应用程序在睡眠后失败。
何Valim

1
@squixy一些使用和定义应用程序的优点罗列如下:stackoverflow.com/questions/30422184/...
何塞·Valim

2
如果您要构建任何长期运行的应用程序,则几乎总是需要一个Supervisor。我曾经Task只是为了拥有最小的正确程序而已,但正如Jose所言-您想在此处启动监督树。
帕维尔Obrok

1
好答案!不过有一个问题。您写道:“仅当您将IO.puts "something"文件放入文件中时,该行仅在编译时求值,而在运行时则不执行任何操作。” 哪个似乎与我所看到的相对应,但我不理解其逻辑?为什么这样工作?
user2104969

10

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

我认为就是您要寻找的。

除此之外mix <task.run>,您还可以运行mix来运行默认任务,而不是。只需添加default_task: "bot.run"def project do [..] endin的列表中即可mix.exs。请参考这里

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.