From: Mike Bayer Date: Fri, 4 Aug 2006 06:21:58 +0000 (+0000) Subject: adjustments to pool stemming from changes made for [ticket:224]. X-Git-Tag: rel_0_2_7~36 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8f94457e56450988d5e18f66ee33dcb26c749caa;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git adjustments to pool stemming from changes made for [ticket:224]. overflow counter should only be decremented if the connection actually succeeded. added a test script to attempt testing this. --- diff --git a/CHANGES b/CHANGES index 487b7c5ba2..da97fff353 100644 --- a/CHANGES +++ b/CHANGES @@ -14,6 +14,9 @@ better error message in PropertyLoader (i.e. relation()/backref()) for when the join condition can't be reasonably determined. - sqlite creates ForeignKeyConstraint objects properly upon table reflection. +- adjustments to pool stemming from changes made for [ticket:224]. +overflow counter should only be decremented if the connection actually +succeeded. added a test script to attempt testing this. 0.2.6 - big overhaul to schema to allow truly composite primary and foreign diff --git a/lib/sqlalchemy/pool.py b/lib/sqlalchemy/pool.py index 7a88ac6f74..d71f645a6e 100644 --- a/lib/sqlalchemy/pool.py +++ b/lib/sqlalchemy/pool.py @@ -102,9 +102,9 @@ class Pool(object): self._purge_for_threadlocal() self.do_return_conn(agent.connection) - def return_invalid(self): + def return_invalid(self, agent): self._purge_for_threadlocal() - self.do_return_invalid() + self.do_return_invalid(agent.connection) def get(self): return self.do_get() @@ -115,7 +115,7 @@ class Pool(object): def do_return_conn(self, conn): raise NotImplementedError() - def do_return_invalid(self): + def do_return_invalid(self, conn): raise NotImplementedError() def status(self): @@ -141,7 +141,7 @@ class ConnectionFairy(object): self.connection = pool.get() except: self.connection = None - self.pool.return_invalid() + self.pool.return_invalid(self) raise if self.pool.echo: self.pool.log("Connection %s checked out from pool" % repr(self.connection)) @@ -149,7 +149,7 @@ class ConnectionFairy(object): if self.pool.echo: self.pool.log("Invalidate connection %s" % repr(self.connection)) self.connection = None - self.pool.return_invalid() + self.pool.return_invalid(self) def cursor(self, *args, **kwargs): return CursorFairy(self, self.connection.cursor(*args, **kwargs)) def __getattr__(self, key): @@ -204,7 +204,7 @@ class SingletonThreadPool(Pool): def do_return_conn(self, conn): pass - def do_return_invalid(self): + def do_return_invalid(self, conn): try: del self._conns[thread.get_ident()] except KeyError: @@ -235,8 +235,9 @@ class QueuePool(Pool): except Queue.Full: self._overflow -= 1 - def do_return_invalid(self): - self._overflow -= 1 + def do_return_invalid(self, conn): + if conn is not None: + self._overflow -= 1 def do_get(self): try: diff --git a/test/perf/poolload.py b/test/perf/poolload.py new file mode 100644 index 0000000000..1b130f568b --- /dev/null +++ b/test/perf/poolload.py @@ -0,0 +1,36 @@ +# this program should open three connections. then after five seconds, the remaining +# 45 threads should receive a timeout error. then the program will just stop until +# ctrl-C is pressed. it should *NOT* open a bunch of new connections. + +from sqlalchemy import * +import sqlalchemy.pool as pool +import psycopg2 as psycopg +import thread,time +psycopg = pool.manage(psycopg,pool_size=2,max_overflow=1, timeout=5, echo=True) +print psycopg +db = create_engine('postgres://scott:tiger@127.0.0.1/test',pool=psycopg,strategy='threadlocal') +print db.connection_provider._pool +metadata = BoundMetaData(db) + +users_table = Table('users', metadata, + Column('user_id', Integer, primary_key=True), + Column('user_name', String(40)), + Column('password', String(10))) +metadata.create_all() + +class User(object): + pass +usermapper = mapper(User, users_table) + +#Then i create loads of threads and in run() of each thread: +def run(): + session = create_session() + transaction = session.create_transaction() + query = session.query(User) + u1=query.select(User.c.user_id==3) + +for x in range(0,50): + thread.start_new_thread(run, ()) + +while True: + time.sleep(5) \ No newline at end of file