Приложение поведение
Модуль для работы с приложениями и определения обратных вызовов приложений.
Приложения — это стандартный способ упаковывать программное обеспечение в 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 предоставляет инструменты, такие как 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()
Получает директорию для app.
Эта информация возвращается на основе пути к коду. Вот пример:
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.
Предупреждение
Вы должны использовать эту функцию только для чтения своей собственной среды приложения. Не читайте среду других приложений.
Среда приложения в info
Если вы пишете библиотеку для использования другими разработчиками, как правило, рекомендуется избегать среды приложения, поскольку среда приложения фактически является глобальным хранилищем. Для получения дополнительной информации, ознакомьтесь с нашими рекомендациями по библиотекам.
fetch_env!(app, key)Source
@spec fetch_env!(app(), key()) :: value()
Возвращает значение для key в среде app.
Если параметр конфигурации не существует, вызывает ArgumentError.
Предупреждение
Вы должны использовать эту функцию только для чтения своей собственной среды приложения. Не читайте среду других приложений.
Среда приложения в info
Если вы пишете библиотеку для использования другими разработчиками, как правило, рекомендуется избегать среды приложения, поскольку среда приложения фактически является глобальным хранилищем. Для получения дополнительной информации, ознакомьтесь с нашими рекомендациями по библиотекам.
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
Обратите внимание, что среда не возвращается, так как к ней можно получить доступ через 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 Plataformatec
Licensed under the Apache License, Version 2.0.
https://hexdocs.pm/elixir/1.15.4/Application.html