如何运行Elixir应用程序?

Kam*_*nek 78 elixir

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

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

mix new app
Run Code Online (Sandbox Code Playgroud)

然后我可以这样做:

mix run
Run Code Online (Sandbox Code Playgroud)

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

IO.puts "running"
Run Code Online (Sandbox Code Playgroud)

lib/app.ex我看到的"running"仅是第一次,每次连续run做什么,除非有一些变化.生成后我可以做什么app.app

我当然知道我能做到:

escript: [main_module: App]
Run Code Online (Sandbox Code Playgroud)

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

mix escript.build
./app
Run Code Online (Sandbox Code Playgroud)

但在我看来,它有点麻烦.

还有类似的东西:

elixir lib/app.exs
Run Code Online (Sandbox Code Playgroud)

但它mix.exs显然不算数,这是我的依赖所需要的app.

Paw*_*rok 95

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
Run Code Online (Sandbox Code Playgroud)

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

defmodule NewMix do
  use Application

  def start(_type, _args) do
    IO.puts "starting"
    # some more stuff
  end
end
Run Code Online (Sandbox Code Playgroud)

start回调实际上应设置您的顶级工艺或监督树的根,但在这种情况下,你会看到已经是它被称为每次使用的时间mix run,虽然紧随其后的错误.

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

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

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

  • 应用程序回调必须返回监督树.如果你没有退回,它将失败.事实上,我甚至会将Paweł显示的最后一个表达式替换为:`Supervisor.start_link [],策略:: one_for_one`.返回关闭的任务可能会导致应用程序在休眠后失败. (17认同)
  • 好吧,这几乎就是我所需要的!还有一件事,你可以解释一下,当没有"任务","代理人"或"主管"等时,"返回了一个错误的值:ok!"错误?这是如何工作的,为什么我们需要一个单独的过程?为什么我不能只运行一些执行我需要的脚本? (4认同)
  • 如果您正在构建任何类型的长期运行应用程序,您几乎总是需要一个"主管".我使用`Task`来获得最小的正确程序,但正如何提到的那样 - 你想在那里启动你的监督树. (2认同)

hol*_*xin 8

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

我想就是你要找的东西.

最重要的是,mix <task.run>您可以简单地运行mix以运行默认任务.只需添加default_task: "bot.run"到列表def project do [..] end中即可mix.exs.请参考这里.