Edgewall Software

Ticket #4984: dont-add-failing-connections-to-the-pool.diff

File dont-add-failing-connections-to-the-pool.diff, 2.8 KB (added by tlk@…, 3 years ago)

do not add failing connections to the pool (0.11-stable)

  • trac/db/pool.py

     
    4141        self._pool = pool 
    4242        self._key = key 
    4343        self._tid = tid 
     44        self._reusable = True 
    4445 
    4546    def close(self): 
    4647        if self.cnx: 
    47             self._pool._return_cnx(self.cnx, self._key, self._tid) 
     48            self._pool._return_cnx(self.cnx, self._key, self._tid, self._reusable) 
    4849            self.cnx = None 
    4950            self.log = None 
    5051 
    5152    def __del__(self): 
    5253        self.close() 
    5354 
     55    def cursor(self): 
     56        try: 
     57            return ConnectionWrapper.cursor(self) 
     58        except Exception: 
     59            self._reusable = False 
     60            self.close() 
     61            raise 
    5462 
    5563def try_rollback(cnx): 
    5664    """Resets the Connection in a safe way, returning True when it succeeds. 
     
    8997            while True: 
    9098                # First choice: Return the same cnx already used by the thread 
    9199                if (tid, key) in self._active: 
    92                     cnx, num = self._active[(tid, key)] 
     100                    cnx, num, reuse = self._active[(tid, key)] 
    93101                    num += 1 
    94102                # Second best option: Reuse a live pooled connection 
    95103                elif key in self._pool_key: 
     
    115123                    self._pool_time.pop(0) 
    116124                    cnx = connector.get_connection(**kwargs) 
    117125                if cnx: 
    118                     self._active[(tid, key)] = (cnx, num) 
     126                    self._active[(tid, key)] = (cnx, num, True) 
    119127                    return PooledConnection(self, cnx, key, tid, log) 
    120128                # Worst option: wait until a connection pool slot is available 
    121129                if timeout and (time.time() - start) > timeout: 
     
    129137        finally: 
    130138            self._available.release() 
    131139 
    132     def _return_cnx(self, cnx, key, tid): 
     140    def _return_cnx(self, cnx, key, tid, reusable): 
    133141        self._available.acquire() 
    134142        try: 
    135143            assert (tid, key) in self._active 
    136             cnx, num = self._active[(tid, key)] 
     144            cnx, num, reuse = self._active[(tid, key)] 
     145            reuse = reuse and reusable 
    137146            if num == 1: 
    138147                del self._active[(tid, key)] 
    139148                self._available.notify()  
    140                 if cnx.poolable and try_rollback(cnx): 
     149                if cnx.poolable and try_rollback(cnx) and reuse: 
    141150                    self._pool.append(cnx) 
    142151                    self._pool_key.append(key) 
    143152                    self._pool_time.append(time.time()) 
    144153            else: 
    145                 self._active[(tid, key)] = (cnx, num - 1) 
     154                self._active[(tid, key)] = (cnx, num - 1, reuse) 
    146155        finally: 
    147156            self._available.release() 
    148157