Author: mysqlpp
Date: Sun Apr 26 05:35:08 2009
New Revision: 2507

URL: http://svn.gna.org/viewcvs/mysqlpp?rev=2507&view=rev
Log:
- Added ConnectionPool::remove(), which takes a Connection*, finds it in
  the pool, and passes the iterator pointing to it to the just-added
  private remove() variant.
- Added exchange(), which wraps remove() and grab().

Modified:
    trunk/Wishlist
    trunk/lib/cpool.cpp
    trunk/lib/cpool.h

Modified: trunk/Wishlist
URL: 
http://svn.gna.org/viewcvs/mysqlpp/trunk/Wishlist?rev=2507&r1=2506&r2=2507&view=diff
==============================================================================
--- trunk/Wishlist (original)
+++ trunk/Wishlist Sun Apr 26 05:35:08 2009
@@ -219,14 +219,6 @@
       allow comparison of row[x] returns to SQL null.  Change one of
       the examples to show it?
 
-       o Add ConnectionPool::remove(), allowing the caller to release a
-         grabbed connection but also cause it to be closed, removed from
-         the pool, such as because an error occurred on it.  Alternately,
-         call it exchange(), passing in a bad connection and getting
-         another back, so caller can loop on a call until it succeeds,
-         purging pool of bad connections.  Reported to be needed when
-         remote server gets restarted.
-
 
 v3.2 Tentative Plan
 -------------------

Modified: trunk/lib/cpool.cpp
URL: 
http://svn.gna.org/viewcvs/mysqlpp/trunk/lib/cpool.cpp?rev=2507&r1=2506&r2=2507&view=diff
==============================================================================
--- trunk/lib/cpool.cpp (original)
+++ trunk/lib/cpool.cpp Sun Apr 26 05:35:08 2009
@@ -85,6 +85,22 @@
 }
 
 
+//// exchange //////////////////////////////////////////////////////////
+// Passed connection is defective, so remove it from the pool and return
+// a new one.
+
+Connection*
+ConnectionPool::exchange(const Connection* pc)
+{
+       // Don't grab the mutex first.  remove() and grab() both do.
+       // Inefficient, but we'd have to hoist their contents up into this
+       // method or extract a mutex-free version of each mechanism for
+       // each, both of which are also inefficient.
+       remove(pc);
+       return grab();
+}
+
+
 //// find_mru //////////////////////////////////////////////////////////
 // Find most recently used available connection.  Uses operator< for
 // ConnectionInfo to order pool with MRU connection last.  Returns 0 if
@@ -140,13 +156,34 @@
 
 
 //// remove ////////////////////////////////////////////////////////////
-// Given an iterator into the pool, destroy the connection and remove
-// it from the pool.  This is only a utility function for use by other
-// class internals.
+// 2 versions:
+//
+// First takes a Connection pointer, finds it in the pool, and calls
+// the second.  It's public, because Connection pointers are all
+// outsiders see of the pool.
+//
+// Second takes an iterator into the pool, destroys the referenced
+// connection and removes it from the pool.  This is only a utility
+// function for use by other class internals.
+
+void
+ConnectionPool::remove(const Connection* pc)
+{
+       ScopedLock lock(mutex_);        // ensure we're not interfered with
+
+       for (PoolIt it = pool_.begin(); it != pool_.end(); ++it) {
+               if (it->conn == pc) {
+                       remove(it);
+                       return;
+               }
+       }
+}
 
 void
 ConnectionPool::remove(const PoolIt& it)
 {
+       // Don't grab the mutex.  Only called from other functions that do
+       // grab it.
        destroy(it->conn);
        pool_.erase(it);
 }
@@ -174,12 +211,7 @@
 {
        Connection* pc;
        while (!(pc = grab())->ping()) {
-               for (PoolIt it = pool_.begin(); it != pool_.end(); ++it) {
-                       if (it->conn == pc) {
-                               remove(it);
-                               break;
-                       }
-               }
+               remove(pc);
        }
 }
 

Modified: trunk/lib/cpool.h
URL: 
http://svn.gna.org/viewcvs/mysqlpp/trunk/lib/cpool.h?rev=2507&r1=2506&r2=2507&view=diff
==============================================================================
--- trunk/lib/cpool.h (original)
+++ trunk/lib/cpool.h Sun Apr 26 05:35:08 2009
@@ -80,6 +80,31 @@
        /// \brief Returns true if pool is empty
        bool empty() const { return pool_.empty(); }
 
+       /// \brief Return a defective connection to the pool and get a new
+       /// one back.
+       ///
+       /// Call this on receiving a BadQuery exception, with errnum()
+       /// equal to CR_SERVER_GONE_ERROR.  It means the server was
+       /// restarted or otherwise dropped your connection to it, so the
+       /// Connection object is no longer usable.  You can avoid the
+       /// need to use this by setting the ReconnectOption in your grab()
+       /// override, but perhaps there are other reasons to need to
+       /// exchange a bad connection for a good one.
+       ///
+       /// This function wraps grab(), not safe_grab(), even though that
+       /// could return another dead connection.  The assumption is that if
+       /// your code is smart enough to detect one bad connection, it should
+       /// be smart enough to detect a whole string of them.  Worst case,
+       /// the whole pool is bad -- remote server went away -- and we have
+       /// to empty the pool and start re-filling it.
+       ///
+       /// \param pc pointer to a Connection object to be returned to the
+       /// pool and marked as unused.
+       ///
+       /// \retval a pointer to a different Connection object; not
+       /// guaranteed to still be connected!
+       virtual Connection* exchange(const Connection* pc);
+
        /// \brief Grab a free connection from the pool.
        ///
        /// This method creates a new connection if an unused one doesn't
@@ -106,7 +131,23 @@
        /// if it doesn't know approximately how long a connection has
        /// really been idle, it can't make good judgements about when to
        /// remove it from the pool.
+       ///
+       /// \param pc pointer to a Connection object to be returned to the
+       /// pool and marked as unused.
        virtual void release(const Connection* pc);
+
+       /// \brief Removes the given connection from the pool
+       ///
+       /// If you mean to simply return a connection to the pool after
+       /// you're finished using it, call release() instead.  This method
+       /// is primarily for error handling: you somehow have figured out
+       /// that the connection is defective, so want it destroyed and
+       /// removed from the pool.  If you also want a different connection
+       /// to retry your operation on, call exchange() instead.
+       ///
+       /// \param pc pointer to a Connection object to be removed from
+       /// the pool and destroyed
+       void remove(const Connection* pc);
 
        /// \brief Grab a free connection from the pool, testing that it's
        /// connected before returning it.


_______________________________________________
Mysqlpp-commits mailing list
[email protected]
https://mail.gna.org/listinfo/mysqlpp-commits

Reply via email to