Як запустити додаток Elixir?


84

Як правильно запустити програму 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.


2
Якщо ви хочете запустити скрипт Elixir ( .exsфайл), але робите це в контексті вашої програми-міксу, ви можете запустити mix run <script>. Дивіться mix help runдодаткову інформацію.
Мішель Тіллі

Відповіді:


106

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

У цьому випадку ми починаємо простий процес у нашому зворотному виклику, який просто перебуває в режимі сну протягом однієї секунди, а потім видає щось - цього достатньо, щоб задовольнити API startзворотного виклику, але ми цього не бачимо "done sleeping". Причиною цього є те, що за замовчуванням mix runбуде закрито після завершення виконання зворотного виклику. Щоб цього не сталося, вам потрібно скористатися mix run --no-halt- у цьому випадку ВМ не буде зупинено.

Ще один корисний спосіб запуску програми iex -S mix- це буде поводитися подібним чином, mix run --no-haltале також відкриватиме iexоболонку, де ви зможете взаємодіяти з вашим кодом та вашим запущеним додатком.


5
Добре, це майже те, що мені потрібно було! Ще одна річ, чи можете ви пояснити цю returned a bad value: :okпомилку, коли її немає Task, Agentабо Supervisorтощо? Як це працює і навіщо нам потрібен окремий процес? Чому я не можу просто запустити якийсь сценарій, який виконує все, що мені потрібно?
Каміль Лелонек

19
Зворотний виклик програми повинен повертати дерево нагляду. Якщо ви не повернете його, він не вдасться. Насправді, я б навіть замінити останній вираз , показане на Paweł по: Supervisor.start_link [], strategy: :one_for_one. Повернення завдання, яке вимикається, може спричинити збій програми після сну.
Хосе Валім

1
@squixy деякі переваги використання та визначення додатків викладені тут: stackoverflow.com/questions/30422184/…
Хосе Валім

2
Якщо ви створюєте будь-який довготривалий додаток, ви майже завжди хочете Supervisor. Я використовував Taskпросто для того, щоб мати найменшу правильну програму, але, як зазначив Хосе, ви хочете там запустити дерево нагляду.
Павел Оброк

1
Чудова відповідь! Хоча одне питання. Ви писали: "Просто коли ви просто додаєте IO.puts "something"файл, рядок обчислюється лише під час компіляції, він нічого не робить під час виконання". що, здається, відповідає тому, що я бачу, але я не розумію логіки цього? Чому це працює так?
user2104969

10

Ви можете запускати завдання, імпортуючи Mix.Taskу ваш модуль замість mix run.

Я думаю, це те, що ви шукаєте.

Крім того, замість цього mix <task.run>ви можете просто запустити mixдля запуску завдання за замовчуванням. Просто додайте default_task: "bot.run"в список def project do [..] endв mix.exs. Зверніться сюди .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.