+
+def _pooled_backend_close(backend):
+ backend._pool.pool_put(backend)
+
+
+from synnefo.lib.pool import ObjectPool
+from new import instancemethod
+from select import select
+from traceback import print_exc
+
+USAGE_LIMIT = 500
+POOL_SIZE = 5
+
+class PithosBackendPool(ObjectPool):
+ def _pool_create(self):
+ backend = _get_backend()
+ backend._real_close = backend.close
+ backend.close = instancemethod(_pooled_backend_close, backend,
+ type(backend))
+ backend._pool = self
+ backend._use_count = USAGE_LIMIT
+ return backend
+
+ def _pool_verify(self, backend):
+ wrapper = backend.wrapper
+ conn = wrapper.conn
+ if conn.closed:
+ return False
+
+ if conn.in_transaction():
+ conn.close()
+ return False
+
+ try:
+ fd = conn.connection.connection.fileno()
+ r, w, x = select([fd], (), (), 0)
+ if r:
+ conn.close()
+ return False
+ except:
+ print_exc()
+ return False
+
+ return True
+
+ def _pool_cleanup(self, backend):
+ c = backend._use_count - 1
+ if c < 0:
+ backend._real_close()
+ return True
+
+ backend._use_count = c
+ wrapper = backend.wrapper
+ if wrapper.trans is not None:
+ conn = wrapper.conn
+ if conn.closed:
+ wrapper.trans = None
+ else:
+ wrapper.rollback()
+ if backend.messages:
+ backend.messages = []
+ return False
+
+_pithos_backend_pool = PithosBackendPool(size=POOL_SIZE)
+
+
+def get_backend():
+ return _pithos_backend_pool.pool_get()
+
+