[erlang-questions] gen_server and multiple workers

David King dking@REDACTED
Thu Aug 30 17:59:03 CEST 2007

I imagine that this is a problem that has been solved a hundred times  
and that I just don't have the right search terms :)

I need to communicate with an outside program, for which I'm using a  
port and a gen_server. However, I may be getting many requests for  
communication to this port at a time, and I don't want to introduce a  
bottleneck in the gen_server, nor do I want to fork() a new instance  
of the program for every request. So I think I'd like to have several  
workers, where each request grabs an available worker (blocking until  
one is available), ideally with some place to put logic to expand or  
reduce the size of the worker-pool with load, but that's optional.  
Having several copies of the external program open at a time isn't a  
problem (it's just a text-transform done by a Perl program).

My gen_server doesn't keep any state except for the Port, so that  
could be managed another way. It seems that I can't combine this with  
gen_server, as gen_server seems to want to register() its PID, and I  
can't have multiple workers with the same register()ed name.

I have a supervisor watching the gen_server. supervisor's required  
export init/1 returns (among other things) a list of processes to  
enter the supervision, but it just calls start_link on the  
gen_server, which registers its name.

I could have the worker-pool managed by the single gen_server  
instance, but I'd like them to be able to crash independently, and it  
seems that that would complicate the handle_call function (as  
gen_server seems to assume that it's synchronous). Complication is  
okay, but I'd like to avoid it if it turns out that there is a single  
library that already does what I want :)

I could also have the supervisor pass in a different name to register  
to gen_server:start_link (worker1,worker2, ...) and have the  
supervisor manage the pool, but that seems messy (which, again, is  
okay, but is to be avoided if possible).

Anyway, I'm sure this is a solved problem and I'm just looking in the  
wrong places. How would you do this?

More information about the erlang-questions mailing list