[erlang-questions] Server which spawns an additional server for each call
Tue Apr 19 14:27:36 CEST 2011
On Apr 19, 2011, at 4:58 AM, Dave Challis wrote:
> I'm trying to work out the structure for a small bit of functionality in erlang. I've got a feeling there's an obvious solution, but I'm not experienced enough with the language sure what pattern to best follow...
> So far, I've got a server which implements the gen_server behaviour, a supervisor for it, and a module containing an API for interacting with it (using gen_server:call mostly).
> The server does a lot of work though, so blocks for a while until the call is finished.
> What I'd like to do, is create a new server process each time gen_server:call is invoked by a client, with each server terminating when it's done processing (but always leaving 1 server running).
> This means that clients using the API will have their request processes straight away, without having to wait for all the other calls to the server to finish.
> I can't quite figure out where to place the logic for doing this though.
> * Should the API module ask the supervisor to spawn a new child, then send the client's call to this?
> * Should API calls go to the supervisor, and have it decide whether to spawn new servers or send the call to an existing one?
> * Or should each server take care of telling the supervisor to spawn a new child, and pass the call request to the newly spawned one?
> Is this a sensible approach in general, or is there an obvious pattern or some functionality I've missed?
What I would do in this situation:
- have a main gen_server module that implements management tasks, and also provides the API to work with the system. This would be supervised by your main app supervisor
- have a bunch of worker gen_servers that implement actual functionality, These would be launched and supervised by a secondary, simple_one_to_one supervisor, that, in turn, would live under the main app supervisor.
- Your manager server would ask your worker supervisor to launch workers on demand and would possibly monitor them
Things can get significantly more complicated if you want to limit the number of spawned workers or you want to have a pool of pre-spawned workers. You could also consider reusing your workers, in order to save process spawning and teardown overhead.
It seems to me that this is a pretty common pattern. I am wondering whether maybe there are already some libraries / generic behaviours out there that implement worker pool functionality. Maybe somebody on this list could point you to something already existing that might save you some work.
Hope this helps,
More information about the erlang-questions