> So the idea is to individually resolve these settings in init callback,
am I getting it right?
https://github.com/elixir-ecto/ecto/blob/master/lib/ecto/repo.ex#L69-L75
> Well, if I do that, I'll have to use the ENV variable in dev environment
as well, which I wouldn't want to do for obvious reasons: these old configs
are just code, when env variables are volatile.

I think you are missing the fact that the resolved environment variable can
be set conditionally, i.e. only when there is _no_ value found in the
application environment. You can do whatever you want in that callback. But
yes, the idea is that if there is no value found at that point, you can
attempt to resolve configuration from the system environment or elsewhere -
it becomes part of your application code and lives alongside the thing
being configured.

> And what is the rationale, why {:system, var} is so bad if what happens
in init callback is essentially the same? Am I missing something here?

It isn't the same - one is implicit, the other explicit, amongst other
things - in addition, the behavior of `{:system, var}` is not well defined,
it depends on the implementation; there is no way to handle converting
values to appropriate internal types (i.e. an atom or an integer) or
provide defaults. There is no way of knowing if that tuple is used for
other purposes in some application or library somewhere or not - the
convention was created by Elixir libraries early on, but there are far more
Erlang libraries and Elixir libraries which do not use it than those which
do, automatically transforming that tuple to the value of the system
environment variable is "magical", and is something we in general try to
avoid, particularly in cases where it may cause issues with existing
applications.

By putting configuration handling code in the `init` callback, you can
handle falling back to multiple sources, perform type conversions,
validation, and more, is explicit, and becomes maintained with your other
application code. If you are looking for something that would do that sort
of conversion for you, you can simply write a thin Config module which
checks for that tuple, and resolves the environment variable, and just
invoke that module from the init callback instead.

Paul



On Mon, Aug 6, 2018 at 8:22 PM Ivan Yurov <ivan.your...@gmail.com> wrote:

> So the idea is to individually resolve these settings in init callback, am
> I getting it right?
> https://github.com/elixir-ecto/ecto/blob/master/lib/ecto/repo.ex#L69-L75
> Well, if I do that, I'll have to use the ENV variable in dev environment
> as well, which I wouldn't want to do for obvious reasons: these old configs
> are just code, when env variables are volatile.
> And what is the rationale, why {:system, var} is so bad if what happens in
> init callback is essentially the same? Am I missing something here?
>
> On Monday, August 6, 2018 at 4:21:34 PM UTC-7, Paul Schoenfelder wrote:
>>
>> In my opinion we absolutely should not support this. It is an old
>> convention that was created to patch over problems with configuration in
>> releases, but it has been considered a bad pattern for quite some time now.
>> Not only are there better patterns available (see Phoenix and Ecto and
>> their init/1 callbacks as one example), but this is something that is being
>> addressed in the release tooling itself - currently with Distillery's
>> config provider framework, and perhaps some variation of that, or a better
>> alternative if one presents itself, when the tooling moves to core.
>>
>> If you have dependencies which still use `{:system, "VAR"}`, you should
>> open issues to encourage maintainers to shift to the `init/1` callback
>> approach, or better, supporting configuration by parameter when possible.
>> The application env should be reserved for global config only.
>>
>> Just my two cents,
>>
>> Paul
>>
>> On Mon, Aug 6, 2018 at 5:33 PM Ivan Yurov <ivan.y...@gmail.com> wrote:
>>
>>> I agree that in general this is not something that should be defined in
>>> the language core or the standard lib.
>>> However, configuration (application env) is already managed by elixir,
>>> and this pattern to access system env var is a widely used by the
>>> libraries, so this might appear confusing for someone, that they set
>>> {:system, var} and it doesn't magically get resolved as it does with many
>>> libraries. :)
>>> Also, there's only one case when it really breaks, — when someone really
>>> wants to return {:system, something} on Application.get_env call, as you
>>> have pointed out. But why would they?
>>>
>>> Thanks, I'll take a closer look at Confex it seems to be doing exactly
>>> what I want. Even though there's a bit more of a boilerplate.
>>>
>>> On Monday, August 6, 2018 at 1:55:30 PM UTC-7, OvermindDL1 wrote:
>>>>
>>>> But what if I want to read it from a data store, or the database, or a
>>>> variety of other places.
>>>>
>>>> A whole configuration handling overhaul has been discussed on the
>>>> forums not long ago:
>>>>
>>>> https://elixirforum.com/t/proposal-moving-towards-discoverable-config-files/14302
>>>>
>>>> For now, https://hex.pm/packages/confex is a decent'ish shim that
>>>> works well enough for build-time configurations though.  :-)
>>>>
>>>> But overall, things like that seem more suited for a configuration
>>>> library (that should be included in Elixir once it is sufficiently generic
>>>> enough and staged enough), though environment variables are common for the
>>>> configs, that doesn't mean that someone really doesn't just want `{:system,
>>>> var}` returned straight though, as can be the case..
>>>>
>>>> :-)
>>>>
>>>>
>>>> On Monday, August 6, 2018 at 1:15:08 PM UTC-6, Ivan Yurov wrote:
>>>>>
>>>>> While playing with deployment I found out that some libraries provide
>>>>> this feature that you can put {:system, var} in configuration and then 
>>>>> it's
>>>>> resolved at runtime. However if it's in my code, I'd have to implement it
>>>>> on my own. Wouldn't it be nice if it was supported by Application module 
>>>>> by
>>>>> default? Something like:
>>>>> def get_env(app, key, default \\ nil) do
>>>>>   case :application.get_env(app, key, default) do
>>>>>     {:system, var} ->
>>>>>       System.get_env(var) || default
>>>>>     rest ->
>>>>>       rest
>>>>>   end
>>>>> end
>>>>>
>>>>> Would it make sense?
>>>>>
>>>> --
>>> You received this message because you are subscribed to the Google
>>> Groups "elixir-lang-core" group.
>>> To unsubscribe from this group and stop receiving emails from it, send
>>> an email to elixir-lang-co...@googlegroups.com.
>>> To view this discussion on the web visit
>>> https://groups.google.com/d/msgid/elixir-lang-core/b4a347ae-baa1-4d79-b906-4108a414b33c%40googlegroups.com
>>> <https://groups.google.com/d/msgid/elixir-lang-core/b4a347ae-baa1-4d79-b906-4108a414b33c%40googlegroups.com?utm_medium=email&utm_source=footer>
>>> .
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>> --
> You received this message because you are subscribed to the Google Groups
> "elixir-lang-core" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to elixir-lang-core+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/elixir-lang-core/cd78f661-96db-451a-a6e4-ed222c53a379%40googlegroups.com
> <https://groups.google.com/d/msgid/elixir-lang-core/cd78f661-96db-451a-a6e4-ed222c53a379%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to elixir-lang-core+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/elixir-lang-core/CAK%3D%2B-TvrnZrSr8B7QVBK8GwqH%2BC1LUwPDU1ofeyhTYXwjjmf9A%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to