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