[erlang-questions] managing multiple instances of a gen_server
Taavi Talvik
taavi@REDACTED
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