How do I have multiple gen_servers, behind a single name, all serving requests?

Logan, Martin Martin.Logan@REDACTED
Mon Aug 7 17:22:10 CEST 2006


For this sort of problem I use an application I call resource_discovery.
When a node starts up resource discovery is configured to tell the
network including the local node about what resources it has and what
resources it is interested in.  The nodes that care about what the new
node has cache those resources and then respond to the new node with the
resources they have that correspond to the resources the newly started
node indicated it was interested in.  In this way all resource discovery
applications have up to date caches of pids for resources that local
applications will require.   This cache of pids is tracked via links.
When a client asks for a resource of a particular type the system hands
it a pid to work with.  The resource_discovery system by default uses a
round robin method to hand out pids in its cache of a given resource
type.

Cheers,
Martin  

-----Original Message-----
From: owner-erlang-questions@REDACTED
[mailto:owner-erlang-questions@REDACTED] On Behalf Of Christian S
Sent: Friday, August 04, 2006 6:02 PM
To: erlang-questions
Subject: How do I have multiple gen_servers, behind a single name, all
serving requests?

Creating connections to databases tend to take some time, most
solutions involve having N connections open in a pool that application
code check out while operating on the db.

As I have found out, database session tend to have a state. For
postgres a prepared statement is given a name that is local to that
session, hidden from other sessions to postgres.
So checking out a connection from a pool, one would have to make sure
these exist by preparing them again, each checkout. Maybe not that
costly in most real situations, but I thought it could be engineered
better:

The idea I got was that you have:
 * one front-end gen_server,
 * it is registered to the name one like to expose,
 * it keeps a fifo or stack of anonymous worker gen_servers
 * to pass on requests any non-busy worker gen_server, quickly going
back wating for more requests
 * and receving info about workers becoming available again.

This would distribute requests over several worker gen_servers. Is
there anything in OTP which does this already? A gen_server option i
missed? pool and overload seem to be concerned with cpu load. I just
want to have several gen_servers so each one can have its own
connection to the database, to avoid the cost of opening new
connections and tap in to the sometimes very good multithreading in
rdbms.

Pooling application gen_servers rather than database connections is
one step up in abstraction. Making it cleaner to write solid
gen_servers that implement "business logic" (sorry for the buzzword).
I mean, succinctly formulated operations the application needs from
the db, such as
decrement-N-units-from-account-A-if-the-balance-is-high-enough:
bank:withdraw(N, A).

Typically gen_servers act as a form of synchronization device, but
here the databases go to great length to handle transactions and their
collisions well.

<<Is this something that could be beneficial for other applications?
given the new SMP scheduler? dns-resolvers come to mind, oddly enough
a remote and of low local processing need database lookup as well.>>



More information about the erlang-questions mailing list