Исходный код Приложение поведение
Модуль для работы с приложениями и определения обратных вызовов приложений.
Приложения — это стандартный способ упаковать программное обеспечение в 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 в один каталог. Выпуски также предоставляют явный контроль над тем, как запускается каждое приложение и в каком порядке. Они также обеспечивают более эффективный механизм запуска и остановки систем, отладки, ведения журналов и мониторинга системы.
Наконец, Elixir предоставляет инструменты, такие как скрипты и архивы, которые являются различными механизмами для упаковки вашего приложения. Они обычно используются, когда инструменты должны быть общими между разработчиками, а не в качестве вариантов развертывания. См. mix help archive.build и mix help escript.build для получения более подробной информации.
Дополнительная информация
Для получения более подробной информации об приложениях, пожалуйста, ознакомьтесь с документацией модуля :application Erlang и разделом Applications руководства по принципам проектирования 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- если приложение должно быть запущено:temporary(по умолчанию),:permanent, или:transient. Дополнительная информация вt:restart_type/1.:mode- (с версии 1.15.0) если приложения должны запускаться последовательно (:serial, по умолчанию) или параллельно (:concurrent). Этот параметр требует 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.
Примеры
Application.put_all_env(
my_app: [
key: :value,
another_key: :another_value
],
another_app: [
key: :value
]
) 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.
Если app не загружено, приложение сначала будет загружено с помощью 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.17.2/Application.html