Spec-Zone.ru › Elixir 1.18

Исходный код Приложение поведение

Модуль для работы с приложениями и определения обратных вызовов приложений.

Приложения — это стандартный способ упаковки программного обеспечения в 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.

Среда приложения в библиотеках

Если вы пишете библиотеку для использования другими разработчиками, обычно рекомендуется избегать среды приложения, так как она по сути является глобальным хранилищем. Дополнительную информацию об этой анти-паттерне читайте в анти-паттерне.

Чтение среды других приложений

Каждое приложение отвечает за свою собственную среду. Не используйте функции этого модуля для прямого доступа или изменения среды других приложений. Всякий раз, когда вы изменяете среду приложения, инструмент сборки 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

Остановка приложения без определения модуля обратного вызова, на практике, является пустой операцией, за исключением некоторых системных трассировок.

Остановка приложения с модулем обратного вызова состоит из трёх шагов:

  1. Если присутствует, вызывается необязательный обратный вызов prep_stop/1.
  2. Завершается супервайзор верхнего уровня.
  3. Вызывается обязательный обратный вызов 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 и к разделу Applications руководства по принципам проектирования OTP .

Краткое описание

Типы

app()
application_key()
key()
restart_type()

Указывает тип приложения

start_type()
state()
value()

Обработчики событий

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.

END_OF_DOCUMENT_MARKER

Типы

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 - (с версии v1.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.

Среда компиляции

Не используйте эту функцию для изменения переменных среды, считываемых через Application.compile_env/2. Среда компиляции должна быть установлена исключительно до компиляции в ваших конфигурационных файлах.

Параметры

  • :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. Обратите внимание, что функция не очищает модули приложения.

Скачать версию ePub

Создано с помощью ExDoc (v0.36.1) для языка программирования Elixir

© 2012-2024 The Elixir Team
Licensed under the Apache License, Version 2.0.
https://hexdocs.pm/elixir/1.18.1/Application.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API