Nebo15 / confex

Useful helper to read and use application configuration from environment variables.
Other
304 stars 33 forks source link

proposal: resolve envs in runtime #38

Closed mapaiva closed 5 years ago

mapaiva commented 5 years ago

Hello,

I've used cofex recently and despite its both clean and straightforward approach strengths, I'm missing something that could boost even more elixir developers lives when doing configs.

Problem

Need to manually resolve configs for every application on your mix project.

Motivation

There's an issue with the manual approach me and my team stumbled on. When using confex for logger application, for instance, logger is resolved before even the project application being executed and for consequence Confex.resolve_env(:logger) being called.

Proposal

Some way to get mix projects configs resolved at runtime, without the need of manually Confex.resolve_env(:app) for each :app.

  1. Create a Confex.Application that resolves all configs for all project applications
  2. Make runtime resolving optional through config e.g.: config :confex, resolver: :runtime
  3. Create docs to start confex as an extra_application when resolving configs at runtime. (Only this step would solve the :logger config issue) e.g.:
  def application do
    [
      mod: {Foo.Application, []},
      extra_applications: [:confex, :logger]
    ]
  end

  defp deps do
    [
      {:confex, "~> 3.3.1", optional: true}
    ]
  end

Thanks in advance for reading, and if you think this change is a good idea, I can personaly help implemeting it, since everthing written in the proposal has been tested and implemented already.

Best, Math

AndrewDryga commented 5 years ago

@mapaiva Hello, thanks for a very detailed proposal. In general, I see the value from configuration options which would tell for which applications we want to resolve environment, but I'm not sure how it works for you in practice.

With extra_applications we can not guarantee that confex would be started before any of applications and this is highly adopted feature nowadays. The only guarantee we have is that confex is started before your application. So looks like it would work in some cases (when confex started before app you tried to configure) and won't work in other ones.

Plus global configuration adds an issue on its own. Imagine that you use dependency that already uses confex and this feature to resolve environment for its dependencies, then use it too and override the value in your app breaking the dependency.

Maybe instead we can add a code snippet to readme which describes use case and solution which can be used in application codebase and a warning for library developers telling not to use it?

P.S. logger is a bad example because it's started 2 times (before anything else to print boot errors and before your app is started) and there is no way to configure its first start.

mapaiva commented 5 years ago

@AndrewDryga thanks for the detailed reply too.

I see your point about telling which app to environment resolve separately, especially in cases where resolving is not feasible such as :logger.

In the described example, I assumed that elixir would respect the start-up order defined on extra_applications which turns out not to be true. Without a deterministic start-up, the logger problem is still there missing the point of the whole solution.

Well, thanks again for the insights. I hope this issue helps folks trying to use confex along with logger in the future 😉

AndrewDryga commented 5 years ago

@mapaiva you are welcome and thank you for using Confex ❤️.

Regarding order, I think it can be controlled if we take look at the internals but because the official documentation does not mention it the order can be changed in the future. And requiring people to take care about start order is error-prone for people not familiar with Confex, they won't expect that it matters, at least I've never seen any libs that do that.