Browse files

#11: Try to recover from closed connections.

  • Loading branch information...
1 parent 0cb7136 commit d63248b2149f9a45e38e97bc366003069a8e1dce @FSX committed Jan 10, 2012
Showing with 23 additions and 12 deletions.
  1. +23 −9 momoko/pools.py
  2. +0 −3 momoko/utils.py
View
32 momoko/pools.py
@@ -9,10 +9,11 @@
:license: MIT, see LICENSE for more details.
"""
-
+import logging
import functools
import psycopg2
+from psycopg2 import DatabaseError, InterfaceError
from psycopg2.extensions import STATUS_READY
from tornado.ioloop import IOLoop, PeriodicCallback
@@ -174,7 +175,6 @@ def _new_conn(self, new_cursor_args={}):
conn = psycopg2.connect(async=1, *self._args, **self._kwargs)
add_conn = functools.partial(self._add_conn, conn)
- # TODO: Pass new argument to indicate a poller is created for a connection
if new_cursor_args:
new_cursor_args['connection'] = conn
new_cursor = functools.partial(self.new_cursor, **new_cursor_args)
@@ -213,13 +213,27 @@ def new_cursor(self, function, func_args=(), callback=None, connection=None):
self._new_conn(new_cursor_args)
return
- cursor = connection.cursor()
- getattr(cursor, function)(*func_args)
-
- # Callbacks from cursor functions always get the cursor back
- if callback:
- callback = functools.partial(callback, cursor)
- Poller(cursor.connection, (callback,), ioloop=self._ioloop).start()
+ try:
+ cursor = connection.cursor()
+ getattr(cursor, function)(*func_args)
+
+ # Callbacks from cursor functions always get the cursor back
+ if callback:
+ cb = functools.partial(callback, cursor)
+ Poller(cursor.connection, (cb,), ioloop=self._ioloop).start()
+ except (DatabaseError, InterfaceError):
+ logging.warning('Requested connection was closed')
+ self._pool.remove(connection)
+ connection = self._get_free_conn()
+ if not connection:
+ new_cursor_args = {
+ 'function': function,
+ 'func_args': func_args,
+ 'callback': callback
+ }
+ self._new_conn(new_cursor_args)
+ else:
+ self.new_cursor(function, func_args, callback, connection)
def _get_free_conn(self):
"""Look for a free connection and return it.
View
3 momoko/utils.py
@@ -137,8 +137,5 @@ def _update_handler(self):
self._io_callback, IOLoop.WRITE)
def _io_callback(self, *args):
- # Maybe keep track of the previous state so you can use update_handler
- # instead of remove/add (Ben Darnell, mailinglist).
- # For connections, not cursors. Cursors are closed after usage.
self._ioloop.remove_handler(self._connection.fileno())
self._update_handler()

0 comments on commit d63248b

Please sign in to comment.