Исходный код Config.Provider поведение
Определяет API провайдера, загружающего конфигурацию во время загрузки.
Провайдеры конфигурации обычно используются во время релизов для загрузки внешней конфигурации во время запуска системы. Это делается путём запуска виртуальной машины с минимальным количеством работающих приложений, вызовом всех провайдеров и последующим перезапуском системы. Это требует изменяемого файла конфигурации на диске, так как результаты работы провайдеров записываются в файловую систему. Дополнительную информацию о конфигурации во время выполнения см. в mix release.
Множественные файлы конфигурации
Одним из распространённых способов использования провайдеров конфигурации является указание нескольких файлов конфигурации в релизе. Elixir поставляется с одним провайдером под названием Config.Reader, способным обрабатывать встроенные файлы конфигурации Elixir.
Например, предположим, что вы хотите вывести некоторую базовую конфигурацию в встроенном файле config/runtime.exs Mix, но также хотите поддерживать дополнительные файлы конфигурации. Для этого вы можете добавить это в раздел def project вашей mix.exs.
releases: [
demo: [
config_providers: [
{Config.Reader, {:system, "RELEASE_ROOT", "/extra_config.exs"}}
]
]
]
Вы можете поместить этот extra_config.exs файл в свой релиз несколькими способами:
Если он доступен на хосте при сборке релиза, вы можете поместить его в "rel/overlays/extra_config.exs", и он будет автоматически скопирован в корень релиза.
Если он доступен на целевой машине во время развертывания, вы можете просто скопировать его в корень релиза в качестве шага в процессе развертывания.
Теперь, когда система загрузится, она загрузит как config/runtime.exs , так и extra_config.exs на ранней стадии процесса загрузки. Вы можете узнать больше об этом на Config.Reader.
Настройка провайдера конфигурации
Вы также можете реализовать собственные провайдеры конфигурации, аналогично тому, как работает Config.Reader. Например, предположим, что вам нужно загрузить некоторую конфигурацию из файла JSON и загрузить её в систему. Данный провайдер конфигурации будет выглядеть так:
defmodule JSONConfigProvider do
@behaviour Config.Provider
# Let's pass the path to the JSON file as config
@impl true
def init(path) when is_binary(path), do: path
@impl true
def load(config, path) do
# We need to start any app we may depend on.
{:ok, _} = Application.ensure_all_started(:jason)
json = path |> File.read!() |> Jason.decode!()
Config.Reader.merge(
config,
my_app: [
some_value: json["my_app_some_value"],
another_value: json["my_app_another_value"],
]
)
end
end
Затем, при определении вашего релиза, вы можете указать провайдера в конфигурации релиза:
releases: [
demo: [
config_providers: [
{JSONConfigProvider, "/etc/config.json"}
]
]
] Резюме
Типы
- config_path()
Путь к файлу конфигурации.
Обработчики
- init(term)
Вызывается при инициализации провайдера конфигурации.
- load(config, state)
Загружает конфигурацию (обычно во время загрузки системы).
Функции
- resolve_config_path!(path)
Преобразует
config_path/0в фактический путь.- validate_config_path!(path)
Проверяет
config_path/0.
Типы
config()Исходный код
@type config() :: keyword()
config_path()Исходный код
@type config_path() :: {:system, binary(), binary()} | binary() Путь к файлу конфигурации.
Поскольку к файлам конфигурации часто обращаются на целевых машинах, их можно представить в виде:
бинарного представления абсолютного пути;
{:system, system_var, path}кортежа, где конфигурация представляет собой конкатенацию переменной окруженияsystem_varс указаннымpath.
state()Исходный код
@type state() :: term()
Обработчики
init(term)Исходный код
@callback init(term()) :: state()
Вызывается при инициализации провайдера конфигурации.
Провайдер конфигурации обычно инициализируется на машине, где система собирается, а не на целевой машине. Обработчик init/1 полезен для проверки переданных провайдеру аргументов и подготовки состояния, которое будет передано load/2.
Кроме того, поскольку состояние, возвращаемое init/1, может быть записано в текстовые файлы конфигурации, оно должно содержать только простые типы данных, такие как целые числа, строки, атомы, кортежи, карты и списки. Элементы, такие как PID, ссылки и функции, сериализовать нельзя.
load(config, state)Исходный код
@callback load(config(), state()) :: config()
Загружает конфигурацию (обычно во время загрузки системы).
Он получает текущую config и state , возвращённую init/1. Затем, обычно, вы читаете дополнительную конфигурацию из внешнего источника и объединяете её с полученной config. Объединение следует выполнять с помощью Config.Reader.merge/2, так как оно выполняет глубокое объединение. Должно быть возвращено обновлённое значение конфигурации.
Обратите внимание, что load/2 обычно вызывается на очень ранней стадии процесса загрузки, поэтому, если вам необходимо использовать приложение в провайдере, вы сами должны его запустить.
Функции
resolve_config_path!(path)Исходный код
@spec resolve_config_path!(config_path()) :: binary()
Преобразует config_path/0 в фактический путь.
validate_config_path!(path)Исходный код
@spec validate_config_path!(config_path()) :: :ok
Проверяет config_path/0.
© 2012-2024 The Elixir Team
Licensed under the Apache License, Version 2.0.
https://hexdocs.pm/elixir/1.17.2/Config.Provider.html