如何运行 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,您可以在其中与您的代码和正在运行的应用程序进行交互。
【讨论】:
好吧,这几乎就是我需要的!还有一件事,当没有Task
、Agent
或Supervisor
等时,你能解释一下这个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 容器内正在运行的应用程序
将 iex shell 附加到正在运行的 elixir 应用程序