Permalink
Browse files

Put operations in a IOLoop callback when no connection is available.

No exception will be raised when the connection pool has no idle
connections. The operation is added as a IOLoop callback and will
be executed when a connection is available.

`mogrify` doesn't need an idle connection, because it only needs some
information from a connection for escaping strings. And the first
connection is the pool will be used for this. An assert has been added
to ensure at least one connection is created in the pool.

A warning message will be shown when there are not enough connections
available.
  • Loading branch information...
1 parent ef3cca6 commit 4ade90bd1e80e8d3c54cfc47990731136d2524d5 @FSX committed Feb 21, 2013
Showing with 26 additions and 22 deletions.
  1. +2 −2 examples/gen_example.py
  2. +20 −20 momoko/connection.py
  3. +4 −0 momoko/utils.py
View
@@ -104,12 +104,12 @@ class MultiQueryHandler(BaseHandler):
def get(self):
cursor1, cursor2, cursor3 = yield [
momoko.Op(self.db.execute, 'SELECT 1;'),
- momoko.Op(self.db.execute, 'SELECT 2;'),
+ momoko.Op(self.db.mogrify, 'SELECT 2;'),
momoko.Op(self.db.execute, 'SELECT %s;', (3*1,))
]
self.write('Query 1 results: %s<br>' % cursor1.fetchall())
- self.write('Query 2 results: %s<br>' % cursor2.fetchall())
+ self.write('Query 2 results: %s<br>' % cursor2)
self.write('Query 3 results: %s' % cursor3.fetchall())
self.finish()
View
@@ -21,7 +21,7 @@
from tornado import gen
from tornado.ioloop import IOLoop, PeriodicCallback
-from .utils import Op
+from .utils import log
from .exceptions import PoolError
@@ -69,6 +69,8 @@ def __init__(self,
callback=None,
ioloop=None
):
+ assert size > 0, 'The connection pool size must be a number above 0.'
+
self.dsn = dsn
self.size = size
self.closed = False
@@ -107,76 +109,74 @@ def _get_connection(self):
def transaction(self,
statements,
cursor_factory=None,
- callback=None,
- connection=None
+ callback=None
):
"""
Run a sequence of SQL queries in a database transaction.
See :py:meth:`momoko.Connection.transaction` for documentation about the
parameters. The ``connection`` parameter is for internal use.
"""
- connection = connection or self._get_connection()
+ connection = self._get_connection()
if not connection:
- raise PoolError('connection pool exausted')
+ log.warning('No connection available, operation queued. Make connection pool bigger?')
+ return self._ioloop.add_callback(partial(self.transaction,
+ statements, cursor_factory, callback))
connection.transaction(statements, cursor_factory, callback)
def execute(self,
operation,
parameters=(),
cursor_factory=None,
- callback=None,
- connection=None
+ callback=None
):
"""
Prepare and execute a database operation (query or command).
See :py:meth:`momoko.Connection.execute` for documentation about the
parameters. The ``connection`` parameter is for internal use.
"""
- connection = connection or self._get_connection()
+ connection = self._get_connection()
if not connection:
- raise PoolError('connection pool exausted')
+ log.warning('No connection available, operation queued. Make connection pool bigger?')
+ return self._ioloop.add_callback(partial(self.execute,
+ operation, parameters, cursor_factory, callback))
connection.execute(operation, parameters, cursor_factory, callback)
def callproc(self,
procname,
parameters=(),
cursor_factory=None,
- callback=None,
- connection=None
+ callback=None
):
"""
Call a stored database procedure with the given name.
See :py:meth:`momoko.Connection.callproc` for documentation about the
parameters. The ``connection`` parameter is for internal use.
"""
- connection = connection or self._get_connection()
+ connection = self._get_connection()
if not connection:
- raise PoolError('connection pool exausted')
+ log.warning('No connection available, operation queued. Make connection pool bigger?')
+ return self._ioloop.add_callback(partial(self.callproc,
+ procname, parameters, cursor_factory, callback))
connection.callproc(procname, parameters, cursor_factory, callback)
def mogrify(self,
operation,
parameters=(),
- callback=None,
- connection=None
+ callback=None
):
"""
Return a query string after arguments binding.
See :py:meth:`momoko.Connection.mogrify` for documentation about the
parameters. The ``connection`` parameter is for internal use.
"""
- connection = connection or self._get_connection()
- if not connection:
- raise PoolError('connection pool exausted')
-
- connection.mogrify(operation, parameters, callback)
+ self._pool[0].mogrify(operation, parameters, callback)
def close(self):
"""
View
@@ -10,6 +10,7 @@
"""
import sys
+import logging
from tornado import gen
from functools import partial
from collections import deque
@@ -21,6 +22,9 @@
is_python_3k = True
+log = logging.getLogger('momoko')
+
+
class Op(gen.Task):
"""
Run a single asynchronous operation.

0 comments on commit 4ade90b

Please sign in to comment.