Что такое Application и как оно инициализируется?
В Elixir Application — это специальный модуль, который служит точкой входа для запуска и управления жизненным циклом вашего проекта. Он предоставляет инфраструктуру для запуска процессов (обычно через Supervisor), настройки конфигурации и управления зависимостями между компонентами.
Основные цели Application
- **Определение точки входа в систему.
** - **Инициализация дерева процессов (обычно Supervisor-дерево).
** - **Загрузка конфигурации.
** - **Автоматический запуск при старте системы или релиза.
** - **Возможность использовать mix release и запуск как службы.
**
Структура Application
Чтобы создать полноценное OTP-приложение, в Elixir нужно:
-
Добавить модуль, реализующий поведение Application.
-
Реализовать колбэк start/2.
-
Указать модуль в mix.exs.
Пример реализации модуля приложения
defmodule MyApp.Application do
use Application
@impl true
def start(\_type, \_args) do
children = \[
{MyApp.Worker, arg}
\]
opts = \[strategy: :one_for_one, name: MyApp.Supervisor\]
Supervisor.start_link(children, opts)
end
end
-
children — список процессов, которые нужно запустить.
-
Supervisor.start_link/2 — инициализирует дерево процессов.
-
opts[:strategy] — стратегия перезапуска (например, :one_for_one).
Объяснение аргументов start/2
-
start/2 вызывается при запуске приложения.
-
Первый аргумент type может принимать значения:
-
:normal — обычный запуск.
-
:takeover — запуск при восстановлении после сбоя.
-
:failover — при передаче управления в кластерной системе.
-
-
Второй аргумент args передаётся при запуске приложения (например, через mix или release).
Указание Application в mix.exs
Файл mix.exs должен содержать ссылку на модуль приложения:
defmodule MyApp.MixProject do
use Mix.Project
def application do
\[
mod: {MyApp.Application, \[\]},
extra_applications: \[:logger\]
\]
end
end
-
mod: {MyApp.Application, []} — указывает, какой модуль вызывать при старте.
-
extra_applications — список зависимостей, запускаемых вместе с вашим приложением (например, :logger, :crypto и т.д.).
Пример рабочего проекта
mix new my_app --sup
Опция --sup автоматически создаёт структуру с Supervisor и Application.
В lib/my_app/application.ex будет уже готовая заготовка Application.
Поведение при остановке
Elixir/OTP предоставляет механизм остановки приложения:
Application.stop(:my_app)
Также вызывается колбэк stop/1, если он реализован:
@impl true
def stop(\_state) do
\# Очистка ресурсов, запись логов и т.д.
:ok
end
Запуск приложения вручную (без Mix)
Если проект собран в .beam и запущен в iex, то приложение можно запустить:
Application.ensure_all_started(:my_app)
Если есть зависимые приложения, они тоже будут автоматически запущены.
Примеры из реальных приложений
Phoenix:
В Phoenix веб-приложениях Application инициализирует веб-сервер, Ecto (базу данных), PubSub и прочее:
children = \[
MyApp.Repo,
MyAppWeb.Endpoint
\]
Nerves:
В Nerves-проектах Application может инициализировать работу с железом, портами и контроллерами.
Работа с конфигурацией приложения
Конфигурация задаётся в config/config.exs, и доступна через:
Application.get_env(:my_app, :key)
Также можно задать переменные в runtime.exs для поддержки mix release:
config :my_app, :api_key, System.get_env("MY_APP_API_KEY")
Зависимости и lifecycle
Если приложение зависит от других библиотек, они автоматически поднимаются при старте, если указаны в mix.exs → applications.
Для инициализации сторонних зависимостей используется Application.ensure_all_started/1.
Связь с Supervisor-деревом
Точка входа в Application.start/2 всегда должна запускать Supervisor — даже если приложение запускает только один процесс. Это основа отказоустойчивости, масштабируемости и структуры Elixir-программ.
Application — фундаментальная абстракция в Elixir/OTP, объединяющая процессы, конфигурацию и контроль жизненного цикла.