Question

I have a piece of erlang code which should read some values from a db and should support a couple of dbs. I wanted my code to be somehow not dependent from the db, so I implemented two different gen_servers that register both with the same atom (db_handler). I decide which version should be started reading the .app file.

The two gen_servers expose a common handle_call, so I can use in other parts of my application something like:

gen_server:call(db_handler, {do_something, "value1", "value2"})

This works, but still it is strongly coupled to the fact that each and any future implementation for a new db should be a gen_server.

I was thinking of using the ! operator and handle the command in the handle_info, but still I think that a better solution is possible (maybe passing through another module?).

Can somebody give me some insight on the better way to handle something like this in erlang?

Était-ce utile?

La solution

For each db server add a common interface to abstract the call:

-module(db_server1).

...

do_something([Value1,Value2]) -> gen_server:call(db_handler, {do_something, "value1", "value2"}).

...

another one not using gen server

-module(db_server2).

...

do_something([Value1,Value2]) -> something_else({do_something, "value1", "value2"}).

...

create a new process (a gen_server :o) which receive as init parameter the param which is used to select the db server and store it in its state (for example db_server2),

for each do_something function, implement a function like:

do_something(Value1,Value2) -> gen_server:call(db_handler, {do_something, ["value1", "value2"]}).

...

handle_call({Func, Args}, _From, DB_server) ->
    R = DB_server:F(Args),
    {reply, R, DB_server}.

same thing for non blocking interfaces, using cast or equivalent

Autres conseils

Each database driver could be a library module that exposes functions for your gen_server.

handle_call({do_something, Driver, Value1, Value2}, _From, State) ->
  Reply = Driver:do_something(Value1, Value2),
  {reply, Reply, State}.
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top