[erlang-questions] Regarding `application:get_env` / `application:set_env` race conditions

Ulf Wiger ulf.wiger@REDACTED
Mon Apr 25 14:55:08 CEST 2011

Hi Ciprian,

The application:set_env/3 function is intended for in-service upgrade, not for the uses you describe.

It is of course a slight problem for non-OTP components that there is no other ubiquitous way of maintaining a configuration database; mnesia is quite a good alternative, for example, but not all systems use it. A dets file would work, but where to put it? There is no standard answer.

A problem with using application:set_env/3, besides the race condition* that you correctly point out, is that it is not persistent, although the application env vars are perceived as a persistent read-only store. This is a problem in the sense that if another process reads an environment variable, they are likely to assume that the value was set at boot time and unlikely to change after that.

I will not present an alternative at this time - although your question gave me an idea. I'll have to think it through a bit first.

Ulf W

On 25 Apr 2011, at 12:17, Ciprian Dorin Craciun wrote:

>    Hello all!
>    I've started studying some popular Erlang applications in order to
> use them in a project of mine.
>    Now I've seen that quite a good proportion of these use the
> application environment as a run-time configuration database -- for
> example a well known web framework uses it for storing routing
> information. (I don't name it here as I don't want this to be taken as
> a criticism. The developers have done a very good overall job and I
> congratulate them for this.)
>    Thus I see more and more the following pattern:
> ~~~~
> ...
> case application:get_env (some_app, some_config) of
>    undefined ->
>        application:set_env (some_app, some_config, [SomeValue]);
>    {ok, OlderValues} ->
>        application:set_env (some_app, some_config, [SomeValue|OlderValues])
> end,
> ...
> ~~~~
>    Thus certainly in a concurrent environment this leads to a race
> condition in which two independent calls to the above code would
> override one each-other. (In some cases this code is hidden behind a
> `gen_server`, thus the access is sequential, but still using this
> environment transforms it into a global shared state, which would
> require other tools.)
>    Thus my two questions are the following:
>    * is it an acceptable pattern in an OTP application to use the
> application environment as a run-time changing database?
>    * shouldn't there be at least an option in the `application`
> module that would allow atomic update of an environment value? (For
> example `update_env(Application, [{Parameter, Fun}])`, which would
> allow updating multiple parameters atomically; (by the way, shouldn't
> this option also be available for ETS / DETS?)
>    Thanks,
>    Ciprian.
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://erlang.org/mailman/listinfo/erlang-questions

Ulf Wiger, CTO, Erlang Solutions, Ltd.

More information about the erlang-questions mailing list