Configuration 将运行时配置传递给elixir进程的正确方法

Configuration 将运行时配置传递给elixir进程的正确方法,configuration,elixir,runtime,gen-server,Configuration,Elixir,Runtime,Gen Server,我试图将一个应用程序部署到生产环境中,但对环境和应用程序变量以及编译时和运行时发生的事情感到有点困惑 在我的应用程序中,我有一个genserver进程,需要令牌才能运行。因此,我使用config/releases.exs在运行时设置令牌变量: # config/releases.exs import Config config :my_app, :my_token, System.fetch_env!("MY_TOKEN") 然后我有一段代码看起来有点像这样: defm

我试图将一个应用程序部署到生产环境中,但对环境和应用程序变量以及编译时和运行时发生的事情感到有点困惑

在我的应用程序中,我有一个genserver进程,需要令牌才能运行。因此,我使用
config/releases.exs
在运行时设置令牌变量:

# config/releases.exs

import Config

config :my_app, :my_token, System.fetch_env!("MY_TOKEN")
然后我有一段代码看起来有点像这样:

defmodule MyApp.SomeService do

  use SomeBehaviour, token: Application.get_env(:my_app, :my_token),
                     other_config: :stuff

  ...

end
在生产过程中,genserver进程(它执行一些http操作)给了我403个错误,表明令牌不存在。因此,我可以澄清一下,
use
关键字是否在编译时得到评估(在这种情况下,应用程序环境还不存在)

如果是这样的话,将运行时环境变量放入这样的服务中的正确方法是什么。启动流程时在
application.ex
中定义配置是否更正确?乙二醇

children = [
  {MyApp.SomeService, [
    token: Application.get_env(:my_app, :my_token),
    other_config: :stuff
  ]}
  ...
]

Supervisor.start_link(children, opts)
我可能已经在这里回答了我自己的问题,但如果有人知道他们在做什么,并为我指出正确的方向,这会很有帮助。谢谢

有两个阶段:编译和运行时,都是用Elixir编写的。为了清楚地理解当我们应该弄明白一切都是宏时会发生什么,Elixir在编译阶段会扩展这些宏,直到一切都被扩展。该AST进入运行时

在您的示例中,
usesomebehavior,foo::bar
隐式调用
somebehavior.\uuuu使用\uuuu/1
宏。要展开AST,还需要展开参数(关键字列表)。因此,
Application.get\u env(:my\u app,:my\u token)
调用在编译时发生

有许多可能将其移动到运行时。如果您是
somebehavior
的所有者,请让它接受对
{:my_app,:my_token}
并调用
应用程序。从其中的某个位置获取\u env/2

或者,如您所建议的,将其作为参数传递给
子对象
;此代码属于函数体,这意味着在编译阶段不会尝试对其进行扩展,而是将其作为AST传递给生成的BEAM以在运行时执行。

有两个阶段:编译和运行时,两者都是用Elixir本身编写的。为了清楚地理解当我们应该弄明白一切都是宏时会发生什么,Elixir在编译阶段会扩展这些宏,直到一切都被扩展。该AST进入运行时

在您的示例中,
usesomebehavior,foo::bar
隐式调用
somebehavior.\uuuu使用\uuuu/1
宏。要展开AST,还需要展开参数(关键字列表)。因此,
Application.get\u env(:my\u app,:my\u token)
调用在编译时发生

有许多可能将其移动到运行时。如果您是
somebehavior
的所有者,请让它接受对
{:my_app,:my_token}
并调用
应用程序。从其中的某个位置获取\u env/2


或者,如您所建议的,将其作为参数传递给
子对象
;此代码属于函数体,这意味着在编译阶段不会尝试对其进行扩展,而是将其作为AST传递给生成的BEAM,以便在运行时执行。

谢谢您的帮助。我是
somebehavior
的所有者,因此,是的,我可以重构它以接受您建议的元组对。与我最初建议的将参数传递给子级相比,我更喜欢这样,因为它将配置/设置保持在一个位置。谢谢你的帮助。我是
somebehavior
的所有者,因此,是的,我可以重构它以接受您建议的元组对。与我最初建议的将参数传递给子级相比,我更喜欢这样,因为它将配置/设置保持在一个位置。谢谢