Aestate
pooled_pg.py
Go to the documentation of this file.
1 try:
2  from Queue import Queue, Empty, Full
3 except ImportError: # Python 3
4  from queue import Queue, Empty, Full
5 
6 from . import __version__
7 from .steady_pg import SteadyPgConnection
8 
9 
10 class PooledPgError(Exception):
11  """General PooledPg error."""
12 
13 
15  """Database connection is invalid."""
16 
17 
19  """Too many database connections were opened."""
20 
21 
22 class PooledPg:
23  """Pool for classic PyGreSQL connections.
24 
25  After you have created the connection pool, you can use
26  connection() to get pooled, steady PostgreSQL connections.
27  """
28 
29  version = __version__
30 
31  def __init__(
32  self, mincached=0, maxcached=0,
33  maxconnections=0, blocking=False,
34  maxusage=None, setsession=None, reset=None,
35  *args, **kwargs):
36  """Set up the PostgreSQL connection pool.
37 
38  mincached: initial number of connections in the pool
39  (0 means no connections are made at startup)
40  maxcached: maximum number of connections in the pool
41  (0 or None means unlimited pool size)
42  maxconnections: maximum number of connections generally allowed
43  (0 or None means an arbitrary number of connections)
44  blocking: determines behavior when exceeding the maximum
45  (if this is set to true, block and wait until the number of
46  connections decreases, otherwise an error will be reported)
47  maxusage: maximum number of reuses of a single connection
48  (0 or None means unlimited reuse)
49  When this maximum usage number of the connection is reached,
50  the connection is automatically reset (closed and reopened).
51  setsession: optional list of SQL commands that may serve to prepare
52  the session, e.g. ["set datestyle to ...", "set time zone ..."]
53  reset: how connections should be reset when returned to the pool
54  (0 or None to rollback transcations started with begin(),
55  1 to always issue a rollback, 2 for a complete reset)
56  args, kwargs: the parameters that shall be used to establish
57  the PostgreSQL connections using class PyGreSQL pg.DB()
58  """
59  self._args, self._kwargs = args, kwargs
60  self._maxusage = maxusage
61  self._setsession = setsession
62  self._reset = reset or 0
63  if mincached is None:
64  mincached = 0
65  if maxcached is None:
66  maxcached = 0
67  if maxconnections is None:
68  maxconnections = 0
69  if maxcached:
70  if maxcached < mincached:
71  maxcached = mincached
72  if maxconnections:
73  if maxconnections < maxcached:
74  maxconnections = maxcached
75  # Create semaphore for number of allowed connections generally:
76  from threading import Semaphore
77  self._connections = Semaphore(maxconnections)
78  self._blocking = blocking
79  else:
80  self._connections = None
81  self._cache = Queue(maxcached) # the actual connection pool
82  # Establish an initial number of database connections:
83  idle = [self.connection() for i in range(mincached)]
84  while idle:
85  idle.pop().close()
86 
87  def steady_connection(self):
88  """Get a steady, unpooled PostgreSQL connection."""
89  return SteadyPgConnection(self._maxusage, self._setsession, True,
90  *self._args, **self._kwargs)
91 
92  def connection(self):
93  """Get a steady, cached PostgreSQL connection from the pool."""
94  if self._connections:
95  if not self._connections.acquire(self._blocking):
96  raise TooManyConnections
97  try:
98  con = self._cache.get(0)
99  except Empty:
100  con = self.steady_connection()
101  return PooledPgConnection(self, con)
102 
103  def cache(self, con):
104  """Put a connection back into the pool cache."""
105  try:
106  if self._reset == 2:
107  con.reset() # reset the connection completely
108  else:
109  if self._reset or con._transaction:
110  try:
111  con.rollback() # rollback a possible transaction
112  except Exception:
113  pass
114  self._cache.put(con, 0) # and then put it back into the cache
115  except Full:
116  con.close()
117  if self._connections:
118  self._connections.release()
119 
120  def close(self):
121  """Close all connections in the pool."""
122  while 1:
123  try:
124  con = self._cache.get(0)
125  try:
126  con.close()
127  except Exception:
128  pass
129  if self._connections:
130  self._connections.release()
131  except Empty:
132  break
133 
134  def __del__(self):
135  """Delete the pool."""
136  try:
137  self.close()
138  except: # builtin Exceptions might not exist any more
139  pass
140 
141 
142 # Auxiliary class for pooled connections
143 
145  """Proxy class for pooled PostgreSQL connections."""
146 
147  def __init__(self, pool, con):
148  """Create a pooled DB-API 2 connection.
149 
150  pool: the corresponding PooledPg instance
151  con: the underlying SteadyPg connection
152  """
153  self._pool = pool
154  self._con = con
155 
156  def close(self):
157  """Close the pooled connection."""
158  # Instead of actually closing the connection,
159  # return it to the pool so it can be reused.
160  if self._con:
161  self._pool.cache(self._con)
162  self._con = None
163 
164  def reopen(self):
165  """Reopen the pooled connection."""
166  # If the connection is already back in the pool,
167  # get another connection from the pool,
168  # otherwise reopen the underlying connection.
169  if self._con:
170  self._con.reopen()
171  else:
172  self._con = self._pool.connection()
173 
174  def __getattr__(self, name):
175  """Proxy all members of the class."""
176  if self._con:
177  return getattr(self._con, name)
178  else:
179  raise InvalidConnection
180 
181  def __del__(self):
182  """Delete the pooled connection."""
183  try:
184  self.close()
185  except: # builtin Exceptions might not exist any more
186  pass
aestate.opera.DBPool.pooled_pg.PooledPgConnection.__getattr__
def __getattr__(self, name)
Definition: pooled_pg.py:174
aestate.opera.DBPool.pooled_pg.PooledPg._kwargs
_kwargs
Definition: pooled_pg.py:55
aestate.opera.DBPool.pooled_pg.PooledPgConnection.close
def close(self)
Definition: pooled_pg.py:156
aestate.opera.DBPool.pooled_pg.PooledPg.steady_connection
def steady_connection(self)
Definition: pooled_pg.py:87
aestate.opera.DBPool.pooled_pg.PooledPg
Definition: pooled_pg.py:22
aestate.opera.DBPool.pooled_pg.PooledPgConnection
Definition: pooled_pg.py:144
aestate.opera.DBPool.pooled_pg.PooledPg._cache
_cache
Definition: pooled_pg.py:77
aestate.opera.DBPool.pooled_pg.InvalidConnection
Definition: pooled_pg.py:14
aestate.opera.DBPool.pooled_pg.PooledPg._maxusage
_maxusage
Definition: pooled_pg.py:56
aestate.opera.DBPool.pooled_pg.PooledPg.__del__
def __del__(self)
Definition: pooled_pg.py:134
aestate.opera.DBPool.pooled_pg.PooledPgConnection._con
_con
Definition: pooled_pg.py:154
aestate.opera.DBPool.pooled_pg.PooledPgError
Definition: pooled_pg.py:10
aestate.opera.DBPool.pooled_pg.PooledPgConnection.reopen
def reopen(self)
Definition: pooled_pg.py:164
aestate.opera.DBPool.pooled_pg.PooledPgConnection._pool
_pool
Definition: pooled_pg.py:153
aestate.opera.DBPool.pooled_pg.PooledPg._blocking
_blocking
Definition: pooled_pg.py:74
aestate.opera.DBPool.pooled_pg.PooledPg.cache
def cache(self, con)
Definition: pooled_pg.py:103
aestate.opera.DBPool.pooled_pg.PooledPg._connections
_connections
Definition: pooled_pg.py:73
aestate.opera.DBPool.pooled_pg.PooledPgConnection.__init__
def __init__(self, pool, con)
Definition: pooled_pg.py:147
aestate.opera.DBPool.pooled_pg.PooledPg.__init__
def __init__(self, mincached=0, maxcached=0, maxconnections=0, blocking=False, maxusage=None, setsession=None, reset=None, *args, **kwargs)
Definition: pooled_pg.py:31
aestate.opera.DBPool.pooled_pg.PooledPg._setsession
_setsession
Definition: pooled_pg.py:57
aestate.opera.DBPool.pooled_pg.PooledPg._reset
_reset
Definition: pooled_pg.py:58
aestate.opera.DBPool.pooled_pg.TooManyConnections
Definition: pooled_pg.py:18
aestate.opera.DBPool.steady_pg.SteadyPgConnection
Definition: steady_pg.py:90
aestate.opera.DBPool.pooled_pg.PooledPg.close
def close(self)
Definition: pooled_pg.py:120
aestate.opera.DBPool.pooled_pg.PooledPg.connection
def connection(self)
Definition: pooled_pg.py:92
aestate.opera.DBPool.pooled_pg.PooledPgConnection.__del__
def __del__(self)
Definition: pooled_pg.py:181