Proposal: connection pooling
| From: | Andreas Karajannis | Date: | Sun, 05 Mar 2000 16:30:13 +0000 |
| Subject: | Proposal: connection pooling | ||
| Groups: | php.version4 | ||
| Request: | Send a blank email to php-version4+get-11533@lists.php.net to get a copy of this message | ||
Here comes my first idea of how to implement database pooling in
multithreaded PHP4 versions.
I was inspired by the connection pooling in AOLServer (see
nsd/dbinit.c).
There are still some open issues:
-Can pools be implemented as an extension module?
The global startup/shutdown functions PHP_GINIT() and PHP_GSHUTDOWN()
could provide a hook to allocate / free the needed data structures
available to all threads.
-AOLServer pools synchronize thread access to pools via condition
variables, this is not available in TSRM, see Ns_Cond type below.
-AOLServer provides a timeout mechanism for closing unneeded
connections. This is done via Ns_ScheduleProc(), an equivalent
isn't available with other servers.
int RegisterPool(max_entries, void (*pool_entry_ctor)(void *),
void (*pool_entry_dtor)(void *));
int GetPoolEntry(int pool, *pdata, int wait);
void ReleasePoolEntry(int pool, *pdata);
void pool_entry_ctor(void *ptr);
void pool_entry_dtor(void *ptr);
To use pools:
-Provide constructor function to allocate connection struct and connect
to DB
-Provide destructor function to disconnect from DB and free connection
struct
-Register the pool on module startup, this returns a pool id
-Register a list destructor for pooled connections that will call
ReleasePoolEntry() on request shutdown or explicit connection closing.
-Call GetPoolEntry() to retrieve a database handle. Register a resource
with ZEND_REGISTER_RESOURCE() and the type you got via
register_list_destructor above
Data structures for Pools:
typedef struct _pool_entry {
void *pdata;
struct pool_entry *next_entry;
struct pool *pool_ptr;
} pool_entry
typedef struct _pool {
int id;
int max_entries;
struct pool_entry *first_entry;
struct pool_entry *last_entry;
Ns_Tls lock;
Ns_Cond waitCond;
Ns_Cond getCond;
void (*pool_entry_ctor)(void *);
void (*pool_entry_dtor)(void *);
} pool;
struct _pools{
struct pool *this_pool;
struct pool *next_pool;
} pools;
Your comments are welcome,
-Andreas