Приложение поведение
Модуль для работы с приложениями и определения обратных вызовов приложений.
Приложения — это стандартный способ упаковать программное обеспечение в Erlang/OTP. По своей сути, они похожи на концепцию «библиотеки», распространенную в других языках программирования, но с некоторыми дополнительными характеристиками.
Приложение — это компонент, реализующий определенную функциональность, со стандартной структурой каталогов, конфигурацией и жизненным циклом. Приложения загружаются, запускаются и останавливаются. Каждое приложение также имеет свою собственную среду, которая предоставляет унифицированный API для конфигурирования каждого приложения.
Разработчики обычно взаимодействуют со средой приложения и его модулем обратных вызовов. Поэтому мы сначала рассмотрим эти темы, прежде чем перейдем к деталям файла ресурсов приложения и его жизненного цикла.
Среда приложения
Каждое приложение имеет свою собственную среду. Среда — это список ключевых слов, сопоставляющий атомы с терминами. Обратите внимание, что эта среда не связана со средой операционной системы.
По умолчанию, среда приложения — это пустой список. В файле mix.exs проекта Mix вы можете установить ключ :env в application/0.
def application do [env: [db_host: "localhost"]] end
Теперь в вашем приложении вы можете прочитать эту среду, используя такие функции, как fetch_env!/2 и другие подобные:
defmodule MyApp.DBClient do
def start_link() do
SomeLib.DBClient.start_link(host: db_host())
end
defp db_host do
Application.fetch_env!(:my_app, :db_host)
end
end
В проектах Mix среду приложения и его зависимостей можно переопределить через файл config/config.exs. Например, пользователь вашего приложения может переопределить переменную среды :db_host следующим образом:
import Config config :my_app, :db_host, "db.local"
Вы также можете динамически изменять среду приложения, используя функции, такие как put_env/3 и delete_env/2. Однако, как правило, каждое приложение отвечает за свою собственную среду. Пожалуйста, не используйте функции в этом модуле для прямого доступа или изменения среды других приложений.
Среда времени компиляции
В предыдущем примере мы читали среду приложения во время выполнения:
defmodule MyApp.DBClient do
def start_link() do
SomeLib.DBClient.start_link(host: db_host())
end
defp db_host do
Application.fetch_env!(:my_app, :db_host)
end
end
Другими словами, ключ среды :db_host для приложения :my_app будет прочитан только тогда, когда MyApp.DBClient будет фактически запущен. Хотя чтение среды приложения во время выполнения является предпочтительным подходом, в некоторых редких случаях вам может потребоваться использовать среду приложения для конфигурирования компиляции определенного проекта. Это часто делается путем вызова get_env/3 вне функции:
defmodule MyApp.DBClient do
@db_host Application.get_env(:my_app, :db_host, "db.local")
def start_link() do
SomeLib.DBClient.start_link(host: @db_host)
end
end
Этот подход имеет одно важное ограничение: если вы измените значение среды приложения после компиляции кода, значение, используемое во время выполнения, не изменится! Например, если вы используете mix release, и в вашем config/releases.exs есть:
config :my_app, :db_host, "db.production"
Это значение не повлияет, так как код был скомпилирован для подключения к «db.local», который, скорее всего, недоступен в производственной среде.
По этим причинам чтение среды приложения во время выполнения должно быть предпочтительным вариантом. Однако, если вам действительно необходимо прочитать среду приложения во время компиляции, мы рекомендуем использовать compile_env/3:
@db_host Application.compile_env(:my_app, :db_host, "db.local")
Используя compile_env/3, такие инструменты, как Mix, будут сохранять значения, используемые во время компиляции, и сравнивать значения компиляции со значениями во время выполнения всякий раз, когда ваша система запускается, вызывая ошибку в случае их различий.
Модуль обратного вызова приложения
Приложения могут загружаться, запускаться и останавливаться. Обычно инструменты сборки, такие как Mix, позаботятся о запуске приложения и всех его зависимостей, но вы также можете сделать это вручную, вызвав:
{:ok, _} = Application.ensure_all_started(:some_app)
При запуске приложения разработчики могут настроить модуль обратного вызова, который выполняет пользовательский код. Разработчики используют этот обратный вызов для запуска дерева управления приложения.
Первый шаг — добавить ключ :mod к определению application/0 в вашем файле mix.exs. Он ожидает кортеж с модулем обратного вызова приложения и аргументом запуска (обычно пустым списком):
def application do
[mod: {MyApp, []}]
end
Модуль MyApp , предоставленный для :mod, должен реализовать поведение Application. Это можно сделать, поместив use Application в этот модуль и реализовав обратный вызов start/2, например:
defmodule MyApp do
use Application
def start(_type, _args) do
children = []
Supervisor.start_link(children, strategy: :one_for_one)
end
end
Обратный вызов start/2 должен создать и связать диспетчер и вернуть {:ok, pid} или {:ok, pid, state}, где pid — PID диспетчера, а state — необязательное состояние приложения. args — второй элемент кортежа, переданного параметру :mod.
Аргумент type , переданный start/2, обычно :normal, за исключением распределенного сценария, где настроены перехваты и отказоустойчивость приложений. Распределенные приложения выходят за рамки этой документации.
При завершении работы приложения вызывается обратный вызов stop/1 после остановки дерева управления приложением временем выполнения. Этот обратный вызов позволяет приложению выполнить завершающую очистку. Аргумент — состояние, возвращенное start/2, если оно было, или [] в противном случае. Значение возвращаемого stop/1 игнорируется.
Используя Application, модули получают реализацию по умолчанию для stop/1, которая игнорирует ее аргумент и возвращает :ok, но это можно переопределить.
Модули обратного вызова приложения также могут реализовать необязательный обратный вызов prep_stop/1. Если он присутствует, prep_stop/1 вызывается до завершения дерева управления. Его аргумент — состояние, возвращенное start/2, если оно было, или [] в противном случае, а его значение возврата передается в stop/1.
Файл ресурсов приложения
В предыдущих разделах мы настроили приложение в разделе application/0 файла mix.exs. В конечном счете, Mix будет использовать эту конфигурацию для создания файла ресурсов приложения application resource file, который называется APP_NAME.app. Например, файл ресурсов приложения приложения OTP ex_unit называется ex_unit.app.
Вы можете узнать больше о генерации файлов ресурсов приложения в документации Mix.Tasks.Compile.App, а также выполнив mix help compile.app.
Жизненный цикл приложения
Загрузка приложений
Приложения загружаются, что означает, что время выполнения находит и обрабатывает их файлы ресурсов:
Application.load(:ex_unit) #=> :ok
При загрузке приложения среда, указанная в его файле ресурсов, объединяется с любыми переопределениями из конфигурационных файлов.
Загрузка приложения не загружает его модули.
На практике вы редко загружаете приложения вручную, поскольку это часть процесса запуска, объясненного ниже.
Запуск приложений
Приложения также запускаются:
Application.start(:ex_unit) #=> :ok
После компиляции вашего приложения запуск вашей системы сводится к запуску текущего приложения и его зависимостей. В отличие от других языков, Elixir не имеет процедуры main, которая отвечает за запуск вашей системы. Вместо этого вы запускаете одно или несколько приложений, каждое со своей логикой инициализации и завершения.
При запуске приложения функция Application.load/1 автоматически вызывается, если она еще не была выполнена. Затем она проверяет, уже ли запущены зависимости, перечисленные в ключе applications файла ресурсов. Наличие хотя бы одной незапущенной зависимости — это состояние ошибки. Функции, такие как ensure_all_started/1, позаботятся о запуске приложения и всех его зависимостей.
Если у приложения не настроен модуль обратного вызова, запуск выполняется на этом этапе. В противном случае вызывается обратный вызов start/2. PID верхнего уровня диспетчера, возвращенный этой функцией, сохраняется временем выполнения для последующего использования, а возвращаемое состояние приложения также сохраняется, если оно есть.
Остановка приложений
Запущенные приложения, наконец, останавливаются:
Application.stop(:ex_unit) #=> :ok
Остановка приложения без модуля обратного вызова определена, но, за исключением некоторых системных отслеживаний, она фактически является операцией бездействия.
Остановка приложения с модулем обратного вызова имеет три шага:
- Если присутствует, вызывается необязательный обратный вызов
prep_stop/1. - Завершается диспетчер верхнего уровня.
- Вызывается обязательный обратный вызов
stop/1.
Аргументы, передаваемые в обратные вызовы, связаны с состоянием, которое необязательно возвращается start/2, и они описаны в разделе о модуле обратного вызова выше.
Важно отметить, что шаг 2 является блокирующим. Завершение работы диспетчера запускает рекурсивную цепочку завершения работы дочерних процессов, поэтому упорядоченное завершение всех дочерних процессов. Обратный вызов stop/1 вызывается только после завершения всего дерева управления.
Чистое завершение работы живой системы можно выполнить, вызвав System.stop/1. Это приведет к остановке каждого приложения в обратном порядке их запуска.
По умолчанию, SIGTERM от операционной системы автоматически переводится в System.stop/0. Вы также можете иметь больший контроль над сигналами операционной системы с помощью функции :os.set_signal/2.
Инструменты
Инструмент сборки Mix автоматизирует большинство задач управления приложениями. Например, mix test автоматически запускает зависимости вашего приложения и само приложение перед запуском тестов. mix run --no-halt запускает ваш текущий проект и может использоваться для запуска долгоживущей системы. См. mix help run.
Разработчики также могут использовать mix release для создания релизов. Релизы могут упаковывать весь исходный код, а также виртуальную машину Erlang в один каталог. Релизы также предоставляют явный контроль над тем, как запускается каждое приложение и в каком порядке. Они также обеспечивают более оптимизированный механизм запуска и остановки систем, отладки, ведения журналов, а также мониторинга системы.
Наконец, Elixir предоставляет инструменты, такие как escripts и архивы, которые являются различными механизмами для упаковки приложения. Обычно они используются, когда инструменты должны быть общими для разработчиков, а не как варианты развертывания. Подробности см. в mix help archive.build и mix help escript.build.
Дополнительная информация
Для получения дополнительной информации об приложениях см. документацию модуля application Erlang и раздел «Приложения» в руководстве пользователя принципов проектирования OTP OTP Design Principles User's Guide.
Краткое описание
Типы
Функции
- app_dir(app)
Получает каталог для приложения.
- app_dir(app, path)
Возвращает указанный путь внутри
app_dir/1.- compile_env(app, key_or_path, default \\ nil)
Считывает среду приложения во время компиляции.
- compile_env!(app, key_or_path)
Считывает среду приложения во время компиляции или генерирует исключение.
- delete_env(app, key, opts \\ [])
Удаляет
keyиз указаннойappсреды.- ensure_all_started(app, type \\ :temporary)
Обеспечивает запуск указанного
appи его приложений.- ensure_loaded(app)
Обеспечивает загрузку данного
app.- ensure_started(app, type \\ :temporary)
Обеспечивает запуск данного
app.- fetch_env(app, key)
Возвращает значение для
keyв средеappв кортеже.- fetch_env!(app, key)
Возвращает значение для
keyв средеapp.- format_error(reason)
Форматирует причину ошибки, возвращаемую
start/2,ensure_started/2,stop/1,load/1иunload/1, возвращает строку.- get_all_env(app)
Возвращает все пары ключ-значение для
app.- get_application(module)
Получает приложение для данного модуля.
- get_env(app, key, default \\ nil)
Возвращает значение для
keyв средеapp.- load(app)
Загружает данное
app.- loaded_applications()
Возвращает список с информацией о загруженных приложениях.
- put_all_env(config, opts \\ [])
Устанавливает среду для нескольких приложений одновременно.
- put_env(app, key, value, opts \\ [])
Устанавливает
valueвkeyдля данногоapp.- spec(app)
Возвращает описание для
app.- spec(app, key)
Возвращает значение для
keyв описанииapp.- start(app, type \\ :temporary)
Запускает данное
app.- started_applications(timeout \\ 5000)
Возвращает список с информацией о приложениях, которые в настоящее время работают.
- stop(app)
Останавливает данное
app.- unload(app)
Выгружает данное
app.
Обработчики
- config_change(changed, new, removed)
Обработчик, вызываемый после обновления кода, если изменилась среда приложения.
- prep_stop(state)
Вызывается перед остановкой приложения.
- start(start_type, start_args)
Вызывается при запуске приложения.
- start_phase(phase, start_type, phase_args)
Запускает приложение в синхронных фазах.
- stop(state)
Вызывается после остановки приложения.
Типы
app()
Спецификации
app() :: atom()
application_key()
Спецификации
application_key() :: :start_phases | :mod | :applications | :included_applications | :registered | :maxT | :maxP | :modules | :vsn | :id | :description
key()
Спецификации
key() :: atom()
restart_type()
Спецификации
restart_type() :: :permanent | :transient | :temporary
start_type()
Спецификации
start_type() :: :normal | {:takeover, node()} | {:failover, node()} state()
Спецификации
state() :: term()
value()
Спецификации
value() :: term()
Функции
app_dir(app)
Спецификации
app_dir(app()) :: String.t()
Возвращает директорию приложения.
Эта информация возвращается на основе пути к коду. Вот пример:
File.mkdir_p!("foo/ebin")
Code.prepend_path("foo/ebin")
Application.app_dir(:foo)
#=> "foo"
Даже если директория пуста и нет файла .app, она всё равно считается директорией приложения, исходя из имени "foo/ebin". Имя может содержать дефис -, который считается версией приложения, и он удаляется для целей поиска:
File.mkdir_p!("bar-123/ebin")
Code.prepend_path("bar-123/ebin")
Application.app_dir(:bar)
#=> "bar-123"
Для получения более подробной информации о путях к коду, обратитесь к модулю Code в Elixir, а также к модулю :code в Erlang.
app_dir(app, path)
Спецификации
app_dir(app(), String.t() | [String.t()]) :: String.t()
Возвращает заданный путь внутри app_dir/1.
Если path является строкой, она будет использована в качестве пути внутри app_dir/1. Если path является списком строк, они будут объединены (см. Path.join/1), и результат будет использован как путь внутри app_dir/1.
Примеры
File.mkdir_p!("foo/ebin")
Code.prepend_path("foo/ebin")
Application.app_dir(:foo, "my_path")
#=> "foo/my_path"
Application.app_dir(:foo, ["my", "nested", "path"])
#=> "foo/my/nested/path" compile_env(app, key_or_path, default \\ nil)
Спецификации
compile_env(app(), key() | list(), value()) :: value()
Считывает среду приложения во время компиляции.
Аналогично get_env/3, за исключением того, что оно должно использоваться для чтения значений во время компиляции. Это позволяет Elixir отслеживать изменения значений конфигурации между временем компиляции и временем выполнения.
Первый аргумент — имя приложения. Второй аргумент key_or_path — это либо атомный ключ, либо путь для обхода при поиске конфигурации, начиная с атомного ключа.
Например, рассмотрим следующую конфигурацию:
config :my_app, :key, [foo: [bar: :baz]]
Мы можем получить доступ к ней во время компиляции как:
Application.compile_env(:my_app, :key) #=> [foo: [bar: :baz]] Application.compile_env(:my_app, [:key, :foo]) #=> [bar: :baz] Application.compile_env(:my_app, [:key, :foo, :bar]) #=> :baz
Также можно задать значение по умолчанию в качестве третьего аргумента. Если какой-либо из ключей на пути отсутствует, используется значение по умолчанию:
Application.compile_env(:my_app, [:unknown, :foo, :bar], :default) #=> :default Application.compile_env(:my_app, [:key, :unknown, :bar], :default) #=> :default Application.compile_env(:my_app, [:key, :foo, :unknown], :default) #=> :default
Задавать путь полезно, чтобы дать Elixir понять, что только определённые пути в большой конфигурации зависят от времени компиляции.
compile_env!(app, key_or_path)
Спецификации
compile_env!(app(), key() | list()) :: value()
Считывает среду приложения во время компиляции, или выводит ошибку.
Это то же самое, что compile_env/3, но оно вызывает ArgumentError, если конфигурация недоступна.
delete_env(app, key, opts \\ [])
Спецификации
delete_env(app(), key(), timeout: timeout(), persistent: boolean()) :: :ok
Удаляет key из заданной app среды.
Получает те же параметры, что и put_env/4. Возвращает :ok.
ensure_all_started(app, type \\ :temporary)
Спецификации
ensure_all_started(app(), restart_type()) ::
{:ok, [app()]} | {:error, {app(), term()}} Убеждается, что заданное app и его приложения запущены.
То же, что start/2, но также запускает приложения, перечисленные в :applications в файле .app, если они ранее не были запущены.
ensure_loaded(app)
Спецификации
ensure_loaded(app()) :: :ok | {:error, term()} Убеждается, что заданное app загружено.
То же, что load/2, но возвращает :ok, если приложение уже было загружено.
ensure_started(app, type \\ :temporary)
Спецификации
ensure_started(app(), restart_type()) :: :ok | {:error, term()} Убеждается, что заданное app запущено.
То же, что start/2, но возвращает :ok, если приложение уже запущено. Это полезно в скриптах и при настройке тестов, где приложения тестов нужно явно запускать:
:ok = Application.ensure_started(:my_test_dep)
fetch_env(app, key)
Спецификации
fetch_env(app(), key()) :: {:ok, value()} | :error Возвращает значение для key в среде app в кортеже.
Если параметр конфигурации не существует, функция возвращает :error.
fetch_env!(app, key)
Спецификации
fetch_env!(app(), key()) :: value()
Возвращает значение для key в среде app.
Если параметр конфигурации не существует, выбрасывает ArgumentError.
Важно: если вы считываете среду приложения во время компиляции, например, внутри определения модуля, а не внутри функции, используйте compile_env!/2.
format_error(reason)
Спецификации
format_error(any()) :: String.t()
Форматирует причину ошибки, возвращённую start/2, ensure_started/2, stop/1, load/1 и unload/1, возвращает строку.
get_all_env(app)
Спецификации
get_all_env(app()) :: [{key(), value()}] Возвращает все пары ключ-значение для app.
get_application(module)
Спецификации
get_application(atom()) :: atom() | nil
Получает приложение для данного модуля.
Приложение находится путём анализа спецификаций всех загруженных приложений. Возвращает nil если модуль не указан ни в одной спецификации приложения.
get_env(app, key, default \\ nil)
Спецификации
get_env(app(), key(), value()) :: value()
Возвращает значение для key в среде app.
Если параметр конфигурации не существует, функция возвращает значение default.
Важно: если вы считываете среду приложения во время компиляции, например, внутри определения модуля, а не внутри функции, используйте compile_env/3.
Важно: при написании библиотеки для использования другими разработчиками, обычно рекомендуется избегать среды приложения, так как среда приложения по сути является глобальным хранилищем. Для получения более подробной информации прочитайте наши руководящие по разработке библиотек.
Примеры
get_env/3 обычно используется для чтения конфигурации ваших приложений OTP. Поскольку конфигурации Mix обычно используются для настройки приложений, мы будем использовать это в качестве иллюстрации.
Рассмотрим новое приложение :my_app. :my_app содержит движок базы данных, который поддерживает пул баз данных. Движку базы данных необходимо знать конфигурацию каждой из этих баз данных, и эта конфигурация предоставляется парами ключ-значение в среде :my_app.
config :my_app, Databases.RepoOne, # A database configuration ip: "localhost", port: 5433 config :my_app, Databases.RepoTwo, # Another database configuration (for the same OTP app) ip: "localhost", port: 20717 config :my_app, my_app_databases: [Databases.RepoOne, Databases.RepoTwo]
Наш движок базы данных, используемый :my_app, должен знать, какие базы данных существуют, и какова конфигурация каждой базы данных. Движок базы данных может вызвать get_env(:my_app, :my_app_databases) для получения списка баз данных (указанных именами модулей). Затем наш движок базы данных может пройтись по каждому хранилищу в списке и затем вызвать get_env(:my_app, Databases.RepoOne) и так далее, чтобы получить конфигурацию каждой из них.
load(app)
Спецификации
load(app()) :: :ok | {:error, term()} Загружает заданное app.
Для загрузки должен быть файл .app в путях загрузки. Также будут загружены все :included_applications.
Загрузка приложения не запускает его и не загружает его модули, но загружает его среду.
loaded_applications()
Спецификации
loaded_applications() :: [{app(), description :: charlist(), vsn :: charlist()}] Возвращает список с информацией о загруженных приложениях.
put_all_env(config, opts \\ [])
Спецификации
put_all_env([{app(), [{key(), value()}]}],
timeout: timeout(),
persistent: boolean()
) :: :ok Установка среды для нескольких приложений одновременно.
Указанная конфигурация не должна:
- содержать одно и то же приложение более одного раза
- содержать один и тот же ключ внутри одного приложения более одного раза
Если эти условия не выполнены, поведение неопределённо (в Erlang/OTP 21 и ранее) или вызовет ошибку (в Erlang/OTP 22 и новее).
Получает те же параметры, что и put_env/4. Возвращает :ok.
put_env(app, key, value, opts \\ [])
Спецификации
put_env(app(), key(), value(), timeout: timeout(), persistent: boolean()) :: :ok
Устанавливает value в key для заданного app.
Параметры
-
:timeout- таймаут изменения (по умолчанию5_000миллисекунд) -
:persistent- сохраняет заданное значение при загрузке и перезагрузке приложения
Если put_env/4 вызывается до загрузки приложения, значения среды приложения, указанные в файле .app, переопределят ранее установленные значения.
Параметр :persistent может быть установлен в true, если необходимо гарантировать, что параметры, установленные с помощью этой функции, не будут переопределены параметрами, определенными в файле ресурсов приложения при загрузке. Это означает, что постоянные значения будут сохраняться после загрузки и перезагрузки приложения.
spec(app)
Спецификации
spec(app()) :: [{application_key(), value()}] | nil Возвращает спецификацию для app.
Возвращаются следующие ключи:
:description:id:vsn:modules:maxP:maxT:registered:included_applications:applications:mod:start_phases
Обратите внимание, что среда не возвращается, так как к ней можно получить доступ через fetch_env/2. Возвращает nil если приложение не загружено.
spec(app, key)
Спецификации
spec(app(), application_key()) :: value() | nil
Возвращает значение для key в спецификации app.
См. spec/1 для поддерживаемых ключей. Если заданный параметр спецификации не существует, эта функция вызовет исключение. Возвращает nil если приложение не загружено.
start(app, type \\ :temporary)
Спецификации
start(app(), restart_type()) :: :ok | {:error, term()} Запускает заданное app.
Если приложение не загружено, оно сначала загрузится с помощью load/1. Любое включённое приложение, определённое в ключе :included_applications файла .app, также будет загружено, но не запущено.
Кроме того, все приложения, перечисленные в ключе :applications, должны быть явно запущены перед запуском данного приложения. В противном случае возвращается {:error, {:not_started, app}}, где app — имя отсутствующего приложения.
Если вы хотите автоматически загрузить и запустить все зависимости приложения app, см. ensure_all_started/2.
Аргумент type определяет тип приложения:
:permanent- еслиappзавершается, завершаются все другие приложения и весь узел.:transient- еслиappзавершается с причиной:normal, об этом сообщается, но другие приложения не завершаются. Если транзиентное приложение завершается аномально, все другие приложения и весь узел также завершаются.:temporary- еслиappзавершается, об этом сообщается, но другие приложения не завершаются (по умолчанию).
Обратите внимание, что всегда можно явно остановить приложение, вызвав stop/1. Независимо от типа приложения, другие приложения не затронутся.
Также обратите внимание, что тип :transient мало пригоден, поскольку при завершении дерева наблюдения причина устанавливается в :shutdown, а не в :normal.
started_applications(timeout \\ 5000)
Спецификации
started_applications(timeout()) :: [
{app(), description :: charlist(), vsn :: charlist()}
] Возвращает список с информацией о приложениях, которые в настоящее время выполняются.
stop(app)
Спецификации
stop(app()) :: :ok | {:error, term()} Останавливает заданное app.
При остановке приложение всё ещё загружено.
unload(app)
Спецификации
unload(app()) :: :ok | {:error, term()} Разгружает заданное app.
Также разгрузит все :included_applications. Обратите внимание, что функция не очищает модули приложения.
Обработчики событий
config_change(changed, new, removed)
Спецификации
config_change(changed, new, removed) :: :ok when changed: keyword(), new: keyword(), removed: [atom()]
Обработчик событий, вызываемый после обновления кода, если изменилась среда приложения.
changed — список ключевых пар с изменёнными значениями в среде приложения. new — список ключевых пар с новыми ключами и их значениями. removed — список удалённых ключей.
prep_stop(state)
Спецификации
prep_stop(state()) :: state()
Вызывается перед остановкой приложения.
Эта функция вызывается перед завершением супервизора верхнего уровня. Она получает состояние, возвращённое start/2, если оно было, или [] в противном случае. Возвращаемое значение затем передаётся в stop/1.
start(start_type, start_args)
Спецификации
start(start_type(), start_args :: term()) ::
{:ok, pid()} | {:ok, pid(), state()} | {:error, reason :: term()} Вызывается при запуске приложения.
Эта функция вызывается, когда приложение запускается с помощью Application.start/2 (и функций на его основе, таких как Application.ensure_started/2). Эта функция должна запускать основной процесс приложения (который должен быть супервизором верхнего уровня дерева наблюдения приложения, если приложение следует принципам проектирования OTP по супервизии).
start_type определяет способ запуска приложения:
-
:normal- используется, если запуск нормальный или если приложение распределённое и запускается на текущем узле из-за переключения с другого узла, а ключ спецификации приложения:start_phasesравен:undefined. -
{:takeover, node}- используется, если приложение распределённое и запускается на текущем узле из-за переключения на узлеnode. -
{:failover, node}- используется, если приложение распределённое и запускается на текущем узле из-за переключения на узлеnode, и ключ спецификации приложения:start_phasesне равен:undefined.
start_args — это аргументы, переданные приложению в ключе спецификации :mod (например, mod: {MyApp, [:my_args]}).
Эта функция должна возвращать {:ok, pid} или {:ok, pid, state} в случае успешного запуска. pid — PID супервизора верхнего уровня. state — произвольный термин, по умолчанию []; если приложение позже остановится, state передаётся в обработчик stop/1 (см. документацию для обработчика stop/1 для получения дополнительной информации).
use Application не предоставляет реализацию обработчика start/2 по умолчанию.
start_phase(phase, start_type, phase_args)
Спецификации
start_phase(phase :: term(), start_type(), phase_args :: term()) ::
:ok | {:error, reason :: term()} Запускает приложение в синхронных фазах.
Эта функция вызывается после завершения start/2, но перед возвратом Application.start/2. Она будет вызываться один раз для каждой фазы запуска, определённой в спецификации приложения (и всех включённых приложений), в порядке их перечисления.
stop(state)
Спецификации
stop(state()) :: term()
Вызывается после остановки приложения.
Эта функция вызывается после остановки приложения, т. е. после остановки его дерева супервизора. Она должна делать противоположное тому, что делал обработчик start/2, и должна выполнять необходимую очистку. Возвращаемое значение этого обработчика игнорируется.
state — состояние, возвращённое start/2, если оно было, или [] в противном случае. Если имеется необязательный обработчик prep_stop/1, то state — его возвращаемое значение.
use Application определяет реализацию этой функции по умолчанию, которая ничего не делает и просто возвращает :ok.
© 2012 Plataformatec
Licensed under the Apache License, Version 2.0.
https://hexdocs.pm/elixir/1.10.4/Application.html