[erlang-questions] managing multiple instances of a gen_server

Taavi Talvik <>
Mon Sep 29 02:19:48 CEST 2008


On Sep 29, 2008, at 12:16 AM, Mark Geib wrote:

> I am new to erlang and building a fairly simple system as a test/ 
> prototype.
>
> I need to be able to dynamically create one->many instances of a
> gen_server process to be used a temporary worker/server.
>
> I have be able in the supervisor of this gen_server to create the  
> child
> spec using the simple_one_for_one type. I can create many of the
> gen_servers, but of course they are not registered, and since they are
> the same module I can not call "into" them. Is there is a best- 
> practices
> method to handle this case, or do I need to simple use messaging, or
> calls to gen_server:call(Pid...) for these gen_servers.??

You can do something like:

{ok,SupervisorPid} = supervisor:start_link(...)

% add new worker dynamically to allready running supervisor
ChildSpec = {"worker_id1",{my_worker_module, start_link, Args},  
transient, brutal_kill, worker, [my_worker_module]},
{ok, NewWorkerPid} = supervisor:start_child(SupervisorPid, ChildSpec)

% "call" this new worker (hopefully no yet restarted and still has  
same pid)
gen_server:call(NewWorkerPid, Arguments_for_worker_call)

You can get list of allready running workers with
supervisor:which_children(SupervisorPid)

Calling into gen_server is just shortcut to gen_server:call(? 
MODULE,...). In this
case you can have only one gen_server instance running, which  
typically is registered
under ?MODULE name. However, name can be arbitrary atom.

http://www.erlang.org/doc/man/gen_server.html#start-4
http://www.erlang.org/doc/man/gen_server.html#call-2

You can also register supervisor and then something like
this in your gen_server module interface functions. But this
works only when it does not matter which worker handles work.
Otherwise worker name should be carried along and find_best_worker
can use it to find appropriate process.

do_job(Args) ->
   Pid = find_best_worker(my_registered_supervisor),
   gen_server:call(Pid, Args).

% actually first worker..
find_best_worker(SupervisorName) ->
   {_, Pid, _, _} = hd(supervisor:which_children(SupervisorName)),
   Pid.


best regards,
taavi



More information about the erlang-questions mailing list