Confusion around Mix config and `Application.get_env`

2,316 views
Skip to first unread message

Myron Marston

unread,
Jun 19, 2015, 3:40:34 PM6/19/15
to elixir-l...@googlegroups.com

Yesterday, I spent a while trying to figure out why my config settings weren’t available after creating a release with exrm, even though the settings were available when running mix test and mix phoenix.server. It was user error on my part, but there’s still something about Application.get_env that confuses me.

I originally had some config settings like this in config/test.exsconfig/dev.exs and config/prod.exs:

config :host_result_caching,
  ttl: 5,
  ttl_check: 1

And I was accessing these config settings with code like:

Application.get_env(:host_result_caching, :ttl_check)

This worked fine when running mix test and mix phoenix.server so I assumed I was doing it correctly. After packaging my app for release with exrm (following the phoenix advanced deployment guide), I discovered that Application.get_env was returning nil for these configs. Eventually I found a stackoverflow post that explained the problem. As the docs for Application.get_env state:

If the specified application is not loaded, or the configuration parameter does
not exist, the function returns the default value.

I don’t have a :host_result_caching application. I was just using that as a namespace for the TTL config settings. I fixed the problem by changing my config too:

config :pirosshki, :host_result_caching, %{
  ttl: 5,
  ttl_check: 1
}

(Pirosshki is the name of my phoenix application). I’m now accessing the config like so:

Application.get_env(:pirosshki, :host_result_caching).ttl_check

…which works great.

However, I’m confused about the fact that Application.get_env is documented to return the default value if the specified application is not loaded, and yet when running mix test and mix phoenix.server, it returned the configured value rather than the default of nil, even though the named application was not running.

Why is this behavior of Application.get_env only in effect when packaging releases via exrm? Is it by design? It would be nice if this behavior was always in effect, so that my tests and local dev server didn’t convince me I was doing it right when I wasn’t.

Thanks,
Myron


José Valim

unread,
Jun 19, 2015, 4:41:15 PM6/19/15
to elixir-l...@googlegroups.com

Why is this behavior of Application.get_env only in effect when packaging releases via exrm? Is it by design? It would be nice if this behavior was always in effect, so that my tests and local dev server didn’t convince me I was doing it right when I wasn’t.


It may be because exrm is filtering the configuration to only include the ones that belong to the list of applications it knows about?

Myron Marston

unread,
Jun 19, 2015, 4:47:30 PM6/19/15
to elixir-l...@googlegroups.com
On Fri, Jun 19, 2015 at 1:40 PM, José Valim <jose....@plataformatec.com.br> wrote:

Why is this behavior of Application.get_env only in effect when packaging releases via exrm? Is it by design? It would be nice if this behavior was always in effect, so that my tests and local dev server didn’t convince me I was doing it right when I wasn’t.


It may be because exrm is filtering the configuration to only include the ones that belong to the list of applications it knows about?

That could explain exrm's behavior.

However, leaving exrm aside for a minute...the docs of `Application.get_env` tell me it will return the default value if there is no application loaded with the provided name.  I haven't defined an application with the name `:host_result_caching`.  So shouldn't `Application.get_env(:host_result_caching, :ttl_check)` return `nil` in all environments?  Seems like either a bug or an inaccuracy in the documentation.

Thanks,
Myron

José Valim

unread,
Jun 19, 2015, 4:55:16 PM6/19/15
to elixir-l...@googlegroups.com
The docs are wrong then:

iex(1)> Application.put_env :foo, :bar, :baz
:ok
iex(2)> Application.get_env :foo, :bar
:baz

We should fix it. :) A PR is very welcome!



José Valim
Skype: jv.ptec
Founder and Director of R&D

--
You received this message because you are subscribed to the Google Groups "elixir-lang-talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-ta...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-talk/CADUxQmtiTHJdnvkADnvZz%3DU8KFZRKcEg_QpoJ%3DFugPpQPP5Cmg%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Myron Marston

unread,
Jun 19, 2015, 5:06:01 PM6/19/15
to elixir-l...@googlegroups.com

I’ll be glad to work up a PR :). Before doing so, I have a few questions:

  • If it doesn’t require the argument to be a loaded application, should the function signature and docs call the arguments key and subkey (or namespace and key) rather than app and key? Seems odd to call it app when it can really be any top-level config key you want.
  • I’m noticing that the erlang docs for :application.get_env say the same thing, but have the same behavior as Elixir’s Application.get_env (I’m assuming Elixir’s just delegates to erlang’s?). Given that Erlang’s docs also do not match with the observed behavior, should we try to the docs updated there, too?
  • Does it make sense to document the exrm “gotcha” so folks know that when using exrm, you do have to pass a loaded application? Exrm isn’t in elixir core so it would be odd to include it in the elixir docs…and yet, this was a major head scratcher for me and it’d be good to help others avoid it.

Myron


--
You received this message because you are subscribed to a topic in the Google Groups "elixir-lang-talk" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/elixir-lang-talk/5yX9hBNEXe0/unsubscribe.
To unsubscribe from this group and all its topics, send an email to elixir-lang-ta...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-talk/CAGnRm4KqGNSnxCETXHjGEuo7Y0HTzQ8bxm2mga8Srgnw3AWMyQ%40mail.gmail.com.

José Valim

unread,
Jun 19, 2015, 5:10:44 PM6/19/15
to elixir-l...@googlegroups.com
  • If it doesn’t require the argument to be a loaded application, should the function signature and docs call the arguments key and subkey (or namespace and key) rather than app and key? Seems odd to call it app when it can really be any top-level config key you want.

No because you should only access your application configuration. Plus applications can define default values in def application in their mix.exs which will be used in case you don't provide any in your config (and win over the one given as argument).
  • I’m noticing that the erlang docs for :application.get_env say the same thing, but have the same behavior as Elixir’s Application.get_env (I’m assuming Elixir’s just delegates to erlang’s?). Given that Erlang’s docs also do not match with the observed behavior, should we try to the docs updated there, too?
Certainly.
  • Does it make sense to document the exrm “gotcha” so folks know that when using exrm, you do have to pass a loaded application? Exrm isn’t in elixir core so it would be odd to include it in the elixir docs…and yet, this was a major head scratcher for me and it’d be good to help others avoid it.

I wouldn't say so. exrm is a tool and it is not Elixir responsibility to warn about gotchas from tools that are not part of its default stack.


Paul Schoenfelder

unread,
Jun 19, 2015, 10:36:07 PM6/19/15
to elixir-l...@googlegroups.com, jose....@plataformatec.com.br
To clarify, this is the expected behavior with :application.get_env in the context of a release, as config.exs is converted to sys.config (which is what is loaded by the VM when the release boots), this is why it's also important to make sure your configuration is associated with an application (even if it's your own). exrm is doing no filtering of configuration for it's part.

Paul

Myron Marston

unread,
Jun 20, 2015, 12:11:58 AM6/20/15
to elixir-l...@googlegroups.com, jose....@plataformatec.com.br
Thanks Paul.  As a complete noob to the erlang/elixir ecosystem, I haven't yet learned about sys.config but your reply was very helpful.

What do you think about adding a note to the [common issues](https://github.com/bitwalker/exrm#common-issues) section of your README documenting this gotcha?

Myron

--
You received this message because you are subscribed to a topic in the Google Groups "elixir-lang-talk" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/elixir-lang-talk/5yX9hBNEXe0/unsubscribe.
To unsubscribe from this group and all its topics, send an email to elixir-lang-ta...@googlegroups.com.

Paul Schoenfelder

unread,
Jun 22, 2015, 11:25:58 AM6/22/15
to elixir-l...@googlegroups.com, jose....@plataformatec.com.br
Sure I can add a note about this, no problem.

Paul
Reply all
Reply to author
Forward
0 new messages