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

Ciprian Dorin Craciun ciprian.craciun@REDACTED
Mon Apr 25 12:17:57 CEST 2011

    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])

    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?)


More information about the erlang-questions mailing list