查看源代码 Config.Provider 行为 (Elixir v1.16.2)

指定一个在启动时加载配置的提供者 API。

配置提供者通常在发布过程中使用,用于在系统启动时加载外部配置。这是通过以最少的应用程序运行来启动 VM,然后调用所有提供者,最后重启系统来完成的。这需要磁盘上的可变配置文件,因为提供者的结果会被写入文件系统。有关运行时配置的更多信息,请参见 mix release.

多个配置文件

配置提供者的一个常见用途是在发布中指定多个配置文件。Elixir 附带一个名为 Config.Reader 的提供者,它能够处理 Elixir 的内置配置文件。

例如,假设你想在 Mix 的内置 config/runtime.exs 文件中列出一些基本配置,但你也想支持额外的配置文件。为此,你可以在 mix.exs 文件的 def project 部分添加以下内容

releases: [
  demo: [
    config_providers: [
      {Config.Reader, {:system, "RELEASE_ROOT", "/extra_config.exs"}}
    ]
  ]
]

你可以通过多种方式将此 extra_config.exs 文件放置到你的发布文件中

  1. 如果在组装发布时它在主机上可用,你可以将其放置在 "rel/overlays/extra_config.exs" 中,它将自动被复制到发布根目录

  2. 如果它在部署时在目标主机上可用,你只需将其复制到发布根目录作为部署步骤之一

现在,一旦系统启动,它将在启动过程的早期加载 config/runtime.exsextra_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"}
    ]
  ]
]

总结

类型

指向配置文件的路径。

回调

在初始化配置提供者时调用。

加载配置(通常在系统启动期间)。

类型

@type config() :: keyword()
@type config_path() :: {:system, binary(), binary()} | binary()

指向配置文件的路径。

由于配置文件通常在目标机器上访问,因此可以表示为

  • 表示绝对路径的二进制

  • 一个 {:system, system_var, path} 元组,其中配置是环境变量 system_var 与给定 path 的串联

@type state() :: term()

回调

@callback init(term()) :: state()

在初始化配置提供者时调用。

配置提供者通常在组装系统的机器上初始化,而不是在目标机器上初始化。 init/1 回调用于验证传递给提供者的参数,并准备将传递给 load/2 的状态。

此外,由于 init/1 返回的状态可以写入基于文本的配置文件,因此应将其限制为简单的类型,例如整数、字符串、原子、元组、映射和列表。PID、引用和函数等条目无法序列化。

@callback load(config(), state()) :: config()

加载配置(通常在系统启动期间)。

它接收当前的 configinit/1 返回的 state。然后,你通常会从外部来源读取额外的配置,并将其合并到接收到的 config 中。合并应该使用 Config.Reader.merge/2 进行,因为它执行深度合并。它应该返回更新后的配置。

请注意,load/2 通常在启动过程的早期被调用,因此如果你需要在提供者中使用应用程序,你有责任启动它。

函数

链接到此函数

resolve_config_path!(path)

查看源代码 (自 1.9.0 起)
@spec resolve_config_path!(config_path()) :: binary()

config_path/0 解析为实际路径。

链接到此函数

validate_config_path!(path)

查看源代码 (自 1.9.0 起)
@spec validate_config_path!(config_path()) :: :ok

验证 config_path/0.