How to configure processes, (and applications)

Vladimir Sekissov svg@REDACTED
Mon Feb 21 18:35:59 CET 2005


Good day,

anders.nygren> In my first OTP based system I had the processes do application:env/1
anders.nygren> whenever they needed the data, but I am not very happy with this.
anders.nygren> 
anders.nygren> Now I am considering having the main supervisor of the application
anders.nygren> read the configuration data and pass it in the start_link calls to the 
anders.nygren> different processes.
anders.nygren> 
anders.nygren> I believe that this will be better, easier to reuse, test before the entire
anders.nygren> system is developed and so on.

I also use the similar approach.  My application usually looks like

                          
                    +------------------------+
                    |  Application supervisor|
                    +------------------------+
                       |                   |
                       |		   |
                       V                   V  
          +--------------+               +----------------------+
          |Config manager|               | Subprocess supervisor|
          +--------------+               +----------------------+
                 ^                                  ...
                 +----------------------------->Subprocesses

Configuration loading is similar to INETs http-server:

0. Application supervisor starts 'Config' manager and 'Subprocess
   supervisor'. They are restarted and killed together(one_for_one policy).

1. Config manager loads configuration data from application environment
or text file.

2. Bootstraps extracting information about subsystem configuration modules.

3. If config was in text file - parse it calling subsystems callbacks
 if exist, callbacks can add their own data. Config is processed in
 the usual top-down-left-right manner. Example:

parse_config(Path=[login, authen], [User], UserContent, _) ->
  {{authen, login, User}, UserContent};
parse_config(Path=[authen], [], Content, _) ->
  Content;
....

4. Prepare config to store in the same manner:

store_config({Key={authen, login, User}, UserInfo}, AllEntries) ->
  {Key, UserInfo ++ find_user_identity(User, AllEntries)};
.....

and store result configuration in desired backend (application env,
ets/mnesia table).

5. Start subprocesses providing
'Config manager' and 'Subprocess supervisor' pids to callbacks:

postload_config(Config, Sup) ->
  EventServer = ?server_spec
  {ok, _} = supervisor:start_child(Sup, EventServer),
  case config:gv_all(Config, event_handler) of
    [] ->
      ok;
    HlrTypes ->
      ok = lists:foreach(fun (T) -> ok = add_relay_handler(T) end, HlrTypes)
  end;

IMHO this way is more verbose but more flexible than direct OTP
one(but compatible).

I can send you code if you want one.

Best Regards,
Vladimir Sekissov




More information about the erlang-questions mailing list