I have a config section which is composed of 2 parts: a static one which I keep in config.exs
and a dynamic one which I add into runtime.exs
. The dynamic part may get changed frequently, hence runtime.exs
I don’t consider using runtime.exs completely for everything
In such cases, what’s the proper way to read this config section:
Application.compile_env(...)
or Application.get_env(...)
?
Read the compile time parts with Application.compile_env(...)
(and a full path to those keys) and the runtime ones with Application.get_env(...)
.
But I want to the whole section.
Application.compile_env(..)
will raise an exception. Therefore, Application.get_env
gets left and will work. But won’t it create some bugs in some specific circumstances?
Elixir raises an expection when you try to change config used at compile time at runtime. This is meant to prevent people from shooting themselfes in the foot, because those runtime changes to config understandably won’t be able to apply back to the compiled code. So either you’re currently falling for that right now or you’re not using your whole “section” at compile time, but still select the whole thing with Application.compile_env
.
1 Like
One of the two, or none. It’s not answered my question
Application.get_env
returns runtime config merged over compile time config, i.e. it’s the conglomeration of the two.
Or are you saying you want to see runtime config only?
No, I want to access the whole section at once. A section includes compile-time and runtime values, though.
# compile-time config
config, :my_app, :my_section,
static1: 1,
static2: "fdsafds",
# dyn1: 999, # this may get changed often
static3: [
a1: 1,
a2: "fdsfds443999",
]
# runtime.exs
# read dyn1 from ENV
# dyn_value = ....
# ....
# then
config, :my_app, :my_section,
dyn1: dyn_value
And yes, I’m currently using Application.get_env(...)
for it.
defmodule MyApp.M1 do
@my_cfg_section Application.get_env(:my_app, :my_section)
# ...........
What my question will become is: are there pitfulls to using Application.get_env(...)
in this case?
Yes. That module attribute @my_cfg_section
will be evaluated at compile time only. So if you run your program at a later time, with a different env var, that module attribute will not have the change.
Consider a function instead…
defmodule MyApp.M1 do
def my_cfg_section do
Application.get_env(:my_app, :my_section)
end
end
1 Like