Was ist der richtige Weg, um eine Elixir-Anwendung auszuführen?
Ich erstelle ein einfaches Projekt von:
mix new app
und danach kann ich tun:
mix run
Das kompiliert meine App im Grunde einmal. Also, wenn ich hinzufüge:
IO.puts "running"
in lib/app.ex
Ich sehe "running"
nur zum ersten Mal, jedes Mal in Folge run
tut nichts , es sei denn , es einige Änderungen gibt. Was kann ich als nächstes mit generiert tun app.app
?
Natürlich weiß ich, dass ich Folgendes tun kann:
escript: [main_module: App]
in mix.exs
, bieten def main(args):
und dann:
mix escript.build
./app
aber es ist meiner Meinung nach etwas umständlich.
Es gibt auch so etwas wie:
elixir lib/app.exs
aber es zählt mix.exs
offensichtlich nicht, was für abhängigkeiten in meinem benötigt wird app
.
.exs
Datei) ausführen möchten, dies jedoch im Kontext Ihrer Mix-App tun, können Sie es ausführenmix run <script>
. Siehemix help run
für weitere Informationen.Antworten:
mix run
führt Ihre App aus. Es ist nur so, dass wenn Sie einfachIO.puts "something"
eine Datei einfügen, diese Zeile nur zur Kompilierungszeit ausgewertet wird, sie zur Laufzeit nichts tut. Wenn Sie möchten, dass beim Starten Ihrer App etwas gestartet wird, müssen Sie dies in Ihrem Programm angebenmix.exs
.Normalerweise möchten Sie eine Top-Ebene
Application
, die gestartet wird. Fügen Sie dazu einemod
Option hinzumix.exs
:def application do [ # this is the name of any module implementing the Application behaviour mod: {NewMix, []}, applications: [:logger] ] end
Und dann müssen Sie in diesem Modul einen Rückruf implementieren, der beim Start der Anwendung aufgerufen wird:
defmodule NewMix do use Application def start(_type, _args) do IO.puts "starting" # some more stuff end end
Der
start
Rückruf sollte tatsächlich Ihren Prozess- oder Überwachungsbaumstamm der obersten Ebene einrichten. In diesem Fall sehen Sie jedoch bereits, dass er bei jeder Verwendung aufgerufen wirdmix run
, obwohl ein Fehler folgt.def start(_type, _args) do IO.puts "starting" Task.start(fn -> :timer.sleep(1000); IO.puts("done sleeping") end) end
In diesem Fall starten wir einen einfachen Prozess in unserem Rückruf, der nur eine Sekunde lang schläft und dann etwas ausgibt - dies reicht aus, um die API des
start
Rückrufs zu erfüllen, aber wir sehen es nicht"done sleeping"
. Der Grund dafür ist, dass standardmäßig beendetmix run
wird, sobald der Rückruf ausgeführt wurde. Damit dies nicht passiert, müssen Sie verwendenmix run --no-halt
- in diesem Fall wird die VM nicht gestoppt.Ein weiterer nützlicher Weg, um Ihre Anwendung zu starten, ist
iex -S mix
- dies verhält sich ähnlich wiemix run --no-halt
eineiex
Shell, öffnet aber auch eine Shell, in der Sie mit Ihrem Code und Ihrer laufenden Anwendung interagieren können.quelle
returned a bad value: :ok
Fehler noch erklären , wenn dies nicht der Fall istTask
, oderAgent
oderSupervisor
usw.? Wie funktioniert das und warum brauchen wir einen separaten Prozess? Warum kann ich nicht einfach ein Skript ausführen, das alles ausführt, was ich brauche?Supervisor.start_link [], strategy: :one_for_one
. Das Zurückgeben einer heruntergefahrenen Aufgabe kann dazu führen, dass die Anwendung nach dem Ruhezustand fehlschlägt.Supervisor
. Ich habe ein verwendetTask
, um das kleinste richtige Programm zu haben, aber wie Jose erwähnt hat, möchten Sie dort Ihren Überwachungsbaum starten.IO.puts "something"
eine Datei einfügen, wird diese Zeile nur zur Kompilierungszeit ausgewertet und zur Laufzeit nicht ausgeführt." was scheint dem zu entsprechen, was ich sehe, aber ich verstehe die Logik davon nicht? Warum funktioniert das so?Sie können Aufgaben ausführen, indem
Mix.Task
Sie statt in Ihr Modul importierenmix run
.Ich denke, das ist was du suchst.
Darüber hinaus
mix <task.run>
können Sie stattdessen einfach ausführenmix
, um die Standardaufgabe auszuführen. Einfachdefault_task: "bot.run"
in die Liste vondef project do [..] end
in aufnehmenmix.exs
. Siehe hier .quelle