db-torque-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From henn...@apache.org
Subject cvs commit: jakarta-turbine-torque/src/java/org/apache/torque/pool ConnectionPool.java
Date Thu, 09 Jan 2003 15:00:35 GMT
henning     2003/01/09 07:00:35

  Modified:    src/java/org/apache/torque/pool ConnectionPool.java
  Log:
  This fixes one of the most sucking bugs in the ConnectionPool handling...
  
  When upgrading from older versions (and config files) to the current
  torque, users might forget that they have to change their expiry timeouts
  from millis to seconds. So we might get 3,600,000 passed along as maxExpiry
  value. In an int. Then we blow it up by x 1000. In an int. Which overflows.
  Which is < 0. Now you have a negative life time and every pool connection
  expires immediately.
  
  So you get lots and lots of new connections to your database. And
  some, like MySQL have a ratio limiter which, at some point, kicks in
  and your application dies with "there seems to be no database running
  on host <xxx>". And it dies at random points without any real indication.
  And (of course) only under load, so you don't find it in your testing.
  
  Morale: Think long and hard about integer arithmetics. Better yet: Use longs.
  
  Revision  Changes    Path
  1.22      +31 -13    jakarta-turbine-torque/src/java/org/apache/torque/pool/ConnectionPool.java
  
  Index: ConnectionPool.java
  ===================================================================
  RCS file: /home/cvs/jakarta-turbine-torque/src/java/org/apache/torque/pool/ConnectionPool.java,v
  retrieving revision 1.21
  retrieving revision 1.22
  diff -u -r1.21 -r1.22
  --- ConnectionPool.java	9 Jan 2003 13:53:57 -0000	1.21
  +++ ConnectionPool.java	9 Jan 2003 15:00:34 -0000	1.22
  @@ -127,7 +127,7 @@
       /**
        * The amount of time in milliseconds that a connection will be pooled.
        */
  -    private int expiryTime = DEFAULT_EXPIRY_TIME;
  +    private long expiryTime = DEFAULT_EXPIRY_TIME;
   
       /**
        * Counter that keeps track of the number of threads that are in
  @@ -190,12 +190,12 @@
               (maxConnections > 0) ? maxConnections : DEFAULT_MAX_CONNECTIONS;
   
           this.expiryTime =
  -            1000 * ((expiryTime > 0) ? expiryTime : DEFAULT_EXPIRY_TIME);
  +            ((expiryTime > 0) ? expiryTime * 1000 : DEFAULT_EXPIRY_TIME);
   
           this.connectionWaitTimeout =
  -            1000 * ((connectionWaitTimeout > 0)
  -                    ? connectionWaitTimeout 
  -                    : DEFAULT_CONNECTION_WAIT_TIMEOUT);
  +            ((connectionWaitTimeout > 0)
  +             ? connectionWaitTimeout * 1000 
  +             : DEFAULT_CONNECTION_WAIT_TIMEOUT);
   
           this.logInterval = 1000 * logInterval;
   
  @@ -274,12 +274,24 @@
               pc = cpds.getPooledConnection(username, password);
           }
           pc.addConnectionEventListener(this);
  +
           // Age some connections so that there will not be a run on the db,
           // when connections start expiring
  +        //
  +        // I did some experimentation here with integers but as this
  +        // is not a really time critical path, we keep the floating
  +        // point calculation.
           long currentTime = System.currentTimeMillis();
  -        double ratio = (1.0 * totalConnections) / maxConnections;
  -        currentTime -= expiryTime * 0.25 * (1.0 - ratio);
  -        timeStamps.put(pc, new Long(currentTime));
  +
  +        double ratio =
  +            new Long(maxConnections - totalConnections).doubleValue() / maxConnections;
  +
  +        long ratioTime =
  +            new Double(currentTime - (expiryTime * ratio)/4).longValue();
  +
  +        ratioTime = (expiryTime < 0 ) ? currentTime : ratioTime;
  +
  +        timeStamps.put(pc, new Long(ratioTime));
           totalConnections++;
           return pc;
       }
  @@ -373,16 +385,22 @@
       /**
        * Helper method which determines whether a connection has expired.
        *
  -     * @param connection The connection to test.
  +     * @param pc The connection to test.
        * @return True if the connection is expired, false otherwise.
        */
  -    private boolean isExpired(PooledConnection connection)
  +    private boolean isExpired(PooledConnection pc)
       {
           // Test the age of the connection (defined as current time
           // minus connection birthday) against the connection pool
           // expiration time.
  -        return (expiryTime < (System.currentTimeMillis()
  -                - ((Long) timeStamps.get(connection)).longValue()));
  +        long birth = ((Long) timeStamps.get(pc)).longValue();
  +        long age   = System.currentTimeMillis() - birth;
  +
  +        boolean dead = (expiryTime > 0) 
  +            ? age > expiryTime
  +            : age > DEFAULT_EXPIRY_TIME;
  +
  +        return dead; // He is dead, Jim.
       }
   
       /**
  
  
  

Mime
View raw message