Исходный код Приложение поведение
Модуль для работы с приложениями и определения обратных вызовов приложений.
Приложения — это стандартный способ упаковки программного обеспечения в 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 и config/runtime.exs. Первый загружается во время сборки, до компиляции вашего кода, а второй — во время выполнения, непосредственно перед запуском вашего приложения. Например, кто-то, использующий ваше приложение, может переопределить переменную среды :db_host следующим образом:
import Config config :my_app, :db_host, "db.local"
Дополнительную информацию можно найти в разделе «Конфигурация» модуля Mix. Вы также можете динамически изменить среду приложения, используя функции, такие как put_env/3 и delete_env/2.
Среда в библиотеках
Файлы конфигурации
config/config.exsиconfig/runtime.exsредко используются библиотеками. Библиотеки обычно определяют свою среду в функцииapplication/0своего модуляmix.exs. Файлы конфигурации в основном используются приложениями для настройки своих библиотек.
Чтение среды других приложений
Каждое приложение отвечает за свою собственную среду. Не используйте функции этого модуля для прямого доступа к среде или её изменения в других приложениях. При каждом изменении среды приложения инструмент сборки Elixir перекомпилирует только файлы, принадлежащие этому приложению. Поэтому если вы читаете среду приложения другого приложения, существует вероятность, что вы будете зависеть от устаревшей конфигурации, поскольку ваш файл не будет перекомпилирован при её изменении.
Среда времени компиляции
В предыдущем примере мы читали среду приложения во время выполнения:
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 фактически запустится. Хотя чтение среды приложения во время выполнения является предпочтительным подходом, в некоторых редких случаях вы можете захотеть использовать среду приложения для настройки компиляции определённого проекта. Однако, если вы попытаетесь получить доступ к Application.fetch_env!/2 вне функции:
defmodule MyApp.DBClient do
@db_host Application.fetch_env!(:my_app, :db_host)
def start_link() do
SomeLib.DBClient.start_link(host: @db_host)
end
end
Вы можете увидеть предупреждения и ошибки:
warning: Application.fetch_env!/2 is discouraged in the module body, use Application.compile_env/3 instead iex:3: MyApp.DBClient ** (ArgumentError) could not fetch application environment :db_host for application :my_app because the application was not loaded nor configured
Это происходит потому, что при определении модулей среда приложения ещё недоступна. К счастью, предупреждение показывает, как решить эту проблему, используя Application.compile_env/3 вместо этого:
defmodule MyApp.DBClient do
@db_host Application.compile_env(:my_app, :db_host, "db.local")
def start_link() do
SomeLib.DBClient.start_link(host: @db_host)
end
end
Разница заключается в том, что compile_env ожидает, что значение по умолчанию будет передано в качестве аргумента, а не использовать функцию def application вашего модуля mix.exs. Кроме того, при использовании 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
use ApplicationПри
use Application, модульApplicationустановит@behaviour Applicationи определит переопределяемое определение функцииstop/1, которая требуется Erlang/OTP.
Обратный вызов 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 будет использовать эту конфигурацию для создания файла файла ресурсов приложения, который называется 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 VM в один каталог. Релизы также предоставляют явный контроль над тем, как и в каком порядке запускается каждое приложение. Они также обеспечивают более эффективный механизм запуска и остановки систем, отладки, ведения журналов и мониторинга системы.
Наконец, Elixir предоставляет инструменты, такие как escripts и архивы, которые являются различными механизмами для упаковки вашего приложения. Обычно они используются, когда инструменты должны быть общими для разработчиков, а не в качестве вариантов развертывания. См. mix help archive.build и mix help escript.build для получения более подробной информации.
Дополнительная информация
Для получения дополнительной информации об приложениях, пожалуйста, обратитесь к документации модуля :application Erlang и к разделу «Приложения» в руководстве по принципам проектирования OTP Приложения.
Обзор
Типы
- restart_type()
Указывает тип приложения
Обработчики событий
- config_change(changed, new, removed)
Обработчик событий, вызываемый после обновления кода, если изменилась среда приложения.
- prep_stop(state)
Вызывается перед остановкой приложения.
- start(start_type, start_args)
Вызывается при запуске приложения.
- start_phase(phase, start_type, phase_args)
Запускает приложение в синхронных фазах.
- stop(state)
Вызывается после остановки приложения.
Функции
- app_dir(app)
Возвращает директорию приложения.
- app_dir(app, path)
Возвращает указанный путь внутри
app_dir/1.- compile_env(app, key_or_path, default \\ nil)
Читает среду приложения во время компиляции.
- compile_env(env, app, key_or_path, default)
Читает среду приложения во время компиляции из макроса.
- compile_env!(app, key_or_path)
Читает среду приложения во время компиляции или вызывает исключение.
- compile_env!(env, app, key_or_path)
Читает среду приложения во время компиляции из макроса или вызывает исключение.
- delete_env(app, key, opts \\ [])
Удаляет
keyиз заданнойappсреды.- ensure_all_started(app_or_apps, type_or_opts \\ [])
Убеждается, что указанные
appилиappsи их дочерние приложения запущены.- ensure_loaded(app)
Убеждается, что заданное
appзагружено.- ensure_started(app, type \\ :temporary)
Убеждается, что указанное
appзапущено сrestart_type/0.- 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сrestart_type/0.- started_applications(timeout \\ 5000)
Возвращает список с информацией о текущих приложениях.
- stop(app)
Останавливает указанное
app.- unload(app)
Выгружает указанное
app.
Типы
app()Source
@type app() :: atom()
application_key()Source
@type application_key() :: :start_phases | :mod | :applications | :optional_applications | :included_applications | :registered | :maxT | :maxP | :modules | :vsn | :id | :description
key()Source
@type key() :: atom()
restart_type()Source
@type restart_type() :: :permanent | :transient | :temporary
Определяет тип приложения:
:permanent- еслиappзавершается, все остальные приложения и весь узел также завершаются.:transient- еслиappзавершается с:normalпричиной, оно сообщается, но другие приложения не завершаются. Если транзиентное приложение завершается аномально, все остальные приложения и весь узел также завершаются.:temporary- еслиappзавершается, оно сообщается, но другие приложения не завершаются (по умолчанию).
Обратите внимание, что всегда можно явно остановить приложение, вызвав stop/1. Независимо от типа приложения, другие приложения не будут затронуты.
Также обратите внимание, что тип :transient мало пригоден на практике, поскольку при завершении дерева надзора причина устанавливается в :shutdown, а не в :normal.
start_type()Source
@type start_type() :: :normal | {:takeover, node()} | {:failover, node()} state()Source
@type state() :: term()
value()Source
@type value() :: term()
Обратные вызовы
config_change(changed, new, removed)Source
@callback config_change(changed, new, removed) :: :ok when changed: keyword(), new: keyword(), removed: [atom()]
Вызывается после обновления кода, если среда приложения изменилась.
changed — это список ключевых слов с изменёнными значениями в среде приложения. new — это список ключевых слов со всеми новыми ключами и их значениями. removed — список всех удалённых ключей.
prep_stop(state)Source
@callback prep_stop(state()) :: state()
Вызывается перед остановкой приложения.
Эта функция вызывается перед завершением супервизора верхнего уровня. Она получает состояние, возвращённое функцией start/2, если оно было возвращено, или [] в противном случае. Возвращаемое значение позже передаётся в функцию stop/1.
start(start_type, start_args)Source
@callback 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)Source
@callback start_phase(phase :: term(), start_type(), phase_args :: term()) ::
:ok | {:error, reason :: term()} Запускает приложение в синхронных фазах.
Эта функция вызывается после завершения start/2, но перед возвращением Application.start/2. Она будет вызвана один раз для каждой фазы запуска, определённой в спецификации приложения (и всех включённых приложений), в порядке их перечисления.
stop(state)Source
@callback stop(state()) :: term()
Вызывается после остановки приложения.
Эта функция вызывается после остановки приложения, т.е. после остановки его дерева надзора. Она должна делать обратное тому, что сделала функция start/2, и должна выполнить необходимую очистку. Возвращаемое значение этого обратного вызова игнорируется.
state — это состояние, возвращённое функцией start/2, если оно было возвращено, или [] в противном случае. Если имеется необязательный обратный вызов prep_stop/1, state будет возвращаемым значением этого обратного вызова вместо этого.
use Application определяет реализацию по умолчанию для этой функции, которая ничего не делает и просто возвращает :ok.
Функции
app_dir(app)Source
@spec 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)Source
@spec 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)Source
@spec 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(env, app, key_or_path, default)Source
@spec compile_env(Macro.Env.t(), app(), key() | list(), value()) :: value()
Считывает среду приложения во время компиляции из макроса.
Обычно разработчики используют compile_env/3. Эта функция должна вызываться только из макросов, которые стремятся динамически считывать среду компиляции.
Ожидает Macro.Env в качестве первого аргумента, где Macro.Env обычно является __CALLER__ в макросе. Возбуждает исключение, если Macro.Env происходит из функции.
compile_env!(app, key_or_path)Source
@spec compile_env!(app(), key() | list()) :: value()
Считывает среду приложения во время компиляции или возбуждает исключение.
Это то же самое, что и compile_env/3, но возбуждает исключение ArgumentError, если конфигурация недоступна.
compile_env!(env, app, key_or_path)Source
@spec compile_env!(Macro.Env.t(), app(), key() | list()) :: value()
Считывает среду приложения во время компиляции из макроса или возбуждает исключение.
Обычно разработчики используют compile_env!/2. Эта функция должна вызываться только из макросов, которые стремятся динамически считывать среду компиляции.
Ожидает Macro.Env в качестве первого аргумента, где Macro.Env обычно является __CALLER__ в макросе. Возбуждает исключение, если Macro.Env происходит из функции.
delete_env(app, key, opts \\ [])Source
@spec delete_env(app(), key(), timeout: timeout(), persistent: boolean()) :: :ok
Удаляет key из заданной app среды.
Принимает те же опции, что и put_env/4. Возвращает :ok.
ensure_all_started(app_or_apps, type_or_opts \\ [])Source
@spec ensure_all_started(app() | [app()],
type: restart_type(),
mode: :serial | :concurrent
) ::
{:ok, [app()]} | {:error, term()} @spec ensure_all_started(app() | [app()], restart_type()) ::
{:ok, [app()]} | {:error, term()} Обеспечивает запуск указанных app или apps и их дочерних приложений.
Второй аргумент — это t:restart_type/1 (для согласованности с start/2) или список ключевых слов.
Опции
:type— если приложение должно быть запущено в:permanent,:temporary, или:transient. См.t:restart_type/1для получения дополнительной информации.:mode— (с версии v1.15.0) если приложения должны запускаться последовательно или параллельно. Эта опция требует Erlang/OTP 26+.
ensure_loaded(app)Source
@spec ensure_loaded(app()) :: :ok | {:error, term()} Обеспечивает загрузку данного app.
То же самое, что и load/1, но возвращает :ok если приложение уже было загружено.
ensure_started(app, type \\ :temporary)Source
@spec ensure_started(app(), restart_type()) :: :ok | {:error, term()} Обеспечивает запуск данного app с типом restart_type/0.
То же самое, что и start/2, но возвращает :ok если приложение уже было запущено.
fetch_env(app, key)Source
@spec fetch_env(app(), key()) :: {:ok, value()} | :error Возвращает значение key в среде app в виде кортежа.
Если параметр конфигурации не существует, функция возвращает :error.
Предупреждение
Вы должны использовать эту функцию только для чтения среды собственного приложения. Не читайте среду других приложений.
Среда приложения в информации
Если вы пишете библиотеку, которую будут использовать другие разработчики, рекомендуется избегать среды приложения, так как среда приложения — это фактически глобальное хранилище. Для получения дополнительной информации ознакомьтесь с нашими руководящими принципами для библиотек.
fetch_env!(app, key)Source
@spec fetch_env!(app(), key()) :: value()
Возвращает значение key в среде app.
Если параметр конфигурации не существует, возбуждает исключение ArgumentError.
Предупреждение
Вы должны использовать эту функцию только для чтения среды собственного приложения. Не читайте среду других приложений.
Среда приложения в информации
Если вы пишете библиотеку, которую будут использовать другие разработчики, рекомендуется избегать среды приложения, так как среда приложения — это фактически глобальное хранилище. Для получения дополнительной информации ознакомьтесь с нашими руководящими принципами для библиотек.
format_error(reason)Source
@spec format_error(any()) :: String.t()
Форматирует причину ошибки, возвращаемую функциями start/2, ensure_started/2, stop/1, load/1 и unload/1, возвращает строку.
get_all_env(app)Source
@spec get_all_env(app()) :: [{key(), value()}] Возвращает все пары ключ-значение для app.
get_application(module)Source
@spec get_application(atom()) :: atom() | nil
Получает приложение для данного модуля.
Приложение находится путём анализа спецификации всех загруженных приложений. Возвращает nil если модуль не указан в спецификации ни одного приложения.
get_env(app, key, default \\ nil)Source
@spec get_env(app(), key(), value()) :: value()
Возвращает значение для key в окружении app.
Если параметр конфигурации не существует, функция возвращает значение default.
Предупреждение
Вы должны использовать эту функцию только для чтения собственного окружения приложения. Не читайте окружение других приложений.
Окружение приложения в библиотеках
Если вы пишете библиотеку, предназначенную для использования другими разработчиками, рекомендуется избегать использования окружения приложения, поскольку оно по сути является глобальным хранилищем. Для получения дополнительной информации прочитайте наши руководящие принципы для библиотек.
Примеры
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, должен знать, какие базы данных существуют и каковы конфигурации баз данных. Движок базы данных может вызвать Application.get_env(:my_app, :my_app_databases, []) для получения списка баз данных (указанных именами модулей).
Затем движок может перебирать каждый репозиторий в списке и вызывать Application.get_env(:my_app, Databases.RepoOne) и так далее для получения конфигурации каждого из них. В этом случае каждая конфигурация будет списком ключевых слов, поэтому вы можете использовать функции в модуле Keyword или даже модуле Access для его обработки, например:
config = Application.get_env(:my_app, Databases.RepoOne) config[:ip]
load(app)Source
@spec load(app()) :: :ok | {:error, term()} Загружает указанное app.
Для загрузки файл .app должен находиться в пути загрузки. Также будут загружены все :included_applications.
Загрузка приложения не запускает его и не загружает его модули, но загружает его окружение.
loaded_applications()Source
@spec loaded_applications() :: [{app(), description :: charlist(), vsn :: charlist()}] Возвращает список с информацией о загруженных приложениях.
put_all_env(config, opts \\ [])Source
@spec put_all_env([{app(), [{key(), value()}]}],
timeout: timeout(),
persistent: boolean()
) :: :ok Одновременно устанавливает окружение для нескольких приложений.
Указанная конфигурация не должна:
- содержать одно и то же приложение более одного раза
- содержать один и тот же ключ внутри одного и того же приложения более одного раза
В противном случае будет выброшено исключение.
Принимает те же опции, что и put_env/4. Возвращает :ok.
put_env(app, key, value, opts \\ [])Source
@spec 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)Source
@spec spec(app()) :: [{application_key(), value()}] | nil Возвращает спецификацию для app.
Возвращаются следующие ключи:
:description:id:vsn:modules:maxP:maxT:registered:included_applications:optional_applications:applications:mod:start_phases
Описание всех полей см. в спецификации приложения Erlang.
Обратите внимание, что окружение не возвращается, так как к нему можно получить доступ через fetch_env/2. Возвращает nil если приложение не загружено.
spec(app, key)Source
@spec spec(app(), application_key()) :: value() | nil
Возвращает значение для key в спецификации app.
См. spec/1 для поддерживаемых ключей. Если заданный параметр спецификации не существует, эта функция выбросит исключение. Возвращает nil если приложение не загружено.
start(app, type \\ :temporary)Source
@spec start(app(), restart_type()) :: :ok | {:error, term()} Запускает данное app с типом restart_type/0.
Если приложение не загружено, сначала оно загружается с помощью load/1. Любое включенное приложение, определённое в ключе :included_applications файла .app, также будет загружено, но не запущено.
Кроме того, все приложения, перечисленные в ключе :applications, должны быть явно запущены до запуска этого приложения. В противном случае возвращается {:error, {:not_started, app}}, где app — имя отсутствующего приложения.
Если вы хотите автоматически загрузить и запустить все зависимости приложения app, см. ensure_all_started/2.
started_applications(timeout \\ 5000)Source
@spec started_applications(timeout()) :: [
{app(), description :: charlist(), vsn :: charlist()}
] Возвращает список с информацией о приложениях, которые в данный момент работают.
stop(app)Source
@spec stop(app()) :: :ok | {:error, term()} Останавливает указанное app.
При остановке приложение всё ещё загружено.
unload(app)Source
@spec unload(app()) :: :ok | {:error, term()} Выгружает указанное app.
Также будут выгружены все :included_applications. Обратите внимание, что функция не очищает модули приложения.
© 2012-2024 The Elixir Team
Licensed under the Apache License, Version 2.0.
https://hexdocs.pm/elixir/1.16.3/Application.html