Date: Wednesday, February 28, 2007 @ 10:53:27
  Author: gilles
    Path: /cvsroot/carob/carob

Modified: include/ControllerPool.hpp (1.14 -> 1.15) src/ControllerPool.cpp
          (1.22 -> 1.23)

Now keeping controller pools 10seconds before deleting them
Cleaned-up remaining debug code
Fixes CAROB-132


----------------------------+
 include/ControllerPool.hpp |   19 +++++++++--
 src/ControllerPool.cpp     |   70 +++++++++++++++++++++++++++++++------------
 2 files changed, 67 insertions(+), 22 deletions(-)


Index: carob/include/ControllerPool.hpp
diff -u carob/include/ControllerPool.hpp:1.14 
carob/include/ControllerPool.hpp:1.15
--- carob/include/ControllerPool.hpp:1.14       Thu Feb  8 12:28:12 2007
+++ carob/include/ControllerPool.hpp    Wed Feb 28 10:53:27 2007
@@ -211,7 +211,11 @@
    * Tells the pool that one of its 'user' (ie. connection) doesn't use it
    * anymore, and return the new number of references
    */
-  int                         removeRef() { ref_counter--; return ref_counter; 
}
+  int                         removeRef();
+  /** Retrieves the number of references left on this instance */
+  int                         getRefCount() { return ref_counter; }
+  /** Returns the last time the number of references was decreased to zero */
+  int64_t                     getLastTimeZeroRef() { return 
last_time_zero_ref; }
   /** Up-to-date list of controllers that respond to pings */
   std::vector<ControllerAndVdbState> alive_controllers;
   /** Mutex on alive controllers */
@@ -221,15 +225,16 @@
   AbstractControllerPool();
   AbstractControllerPool(AbstractControllerPool&);
   AbstractControllerPool& operator=(AbstractControllerPool&);
-
   /** Controller watcher thread */
   ControllerWatcher*          watcher_ptr;
   /** Associated pthread */
   pthread_t                   watcher_thread;
   /** Callback for controller failures and come backs */
   SocketKillerCallback*       callback_ptr;
-  /** references counter managed by controller pool manager */
+  /** References counter managed by controller pool manager */
   int                         ref_counter;
+  /** Last time this instance saw its ref_counter decreased to zero */
+  int64_t                     last_time_zero_ref;
 };
 
 /**
@@ -293,6 +298,8 @@
   bool operator()(const PoolIndex& pi1, const PoolIndex& pi2) const;
 };
 
+/** Number of milliseconds to wait before deleting a pool that is not used */
+#define POOL_TIMEOUT_IN_MS 10000 /* 10s */
 /**
  * Holds a list of controller pools, that are indexed by their policy and list 
  * of controllers. Permits to have only one instance of ControllerPool for the
@@ -329,6 +336,12 @@
    */
   static void                     freePool(AbstractControllerPool* pool);
 protected:
+  /**
+   * Walks through the pool map to look for pools that can be deleted, ie.
+   * a pool that is not used anymore and that been freed at least 
POOL_TIMEOUTms
+   * ago
+   */
+  static void                     tryTocleanUpPools();
 private:
   /** To manage pool map concurrent accesses */
   static CriticalSection          pool_map_CS;
Index: carob/src/ControllerPool.cpp
diff -u carob/src/ControllerPool.cpp:1.22 carob/src/ControllerPool.cpp:1.23
--- carob/src/ControllerPool.cpp:1.22   Mon Feb 26 18:28:23 2007
+++ carob/src/ControllerPool.cpp        Wed Feb 28 10:53:27 2007
@@ -173,6 +173,14 @@
   return sRet;
 }
 
+int AbstractControllerPool::removeRef()
+{
+  ref_counter--;
+  if (ref_counter < 1)
+    last_time_zero_ref = currentTimeMillis();
+  return ref_counter;
+}
+
 
////////////////////////////////////////////////////////////////////////////////
 //                             ROUND ROBIN POLICY
 
////////////////////////////////////////////////////////////////////////////////
@@ -184,21 +192,12 @@
 index(-1)
 {
 }
-#include <iostream>
-using namespace std;
+
 ControllerInfo RoundRobinControllerPool::getController()
     throw (NoMoreControllerException, UnexpectedException)
 {
   const wchar_t fctName[] = L"RoundRobinControllerPool::getController";
   LockScope ls(&pool_CS);
-/*  if (alive_controllers.empty())
-    throw NoMoreControllerException(L"All controllers down");
-  index = (index + 1) % alive_controllers.size();
-  if (isDebugEnabled())
-    logDebug(fctName, L"Selected controller[" + toUserString(index) + L"]:"
-        + static_cast<wstring>(alive_controllers[index]));
-  return alive_controllers[index].controller;
-*/
   int nbOfControllers = alive_controllers.size();
   if (nbOfControllers == 0)
     throw NoMoreControllerException(L"All controllers down");
@@ -224,7 +223,6 @@
     if (index >= nbOfControllers)
       index = 0;
     nbTested++;
-cout<<"index = "<<index<<endl;
     ctrl = alive_controllers[index];
   }
   // all controllers tested, no more available
@@ -298,6 +296,7 @@
       logDebug(fctName, L"Reusing pool \""
           + static_cast<wstring>(*(pool->second)) + L"\"");
     pool->second->addRef();
+    tryTocleanUpPools();
     return *(pool->second);
   }
   // if the pool was not found, let's create a new one
@@ -308,16 +307,47 @@
       new_pool = new RoundRobinControllerPool(ctrls, pingDelayInMs, 
controllerTimeoutInMs);
     break;
     default:
+      tryTocleanUpPools();
       throw DriverException(L"Unsupported connection policy #" + 
toUserString(static_cast<int>(cp)));
   }
   new_pool->addRef();
   pool_map[idx] = static_cast<AbstractControllerPool*>(new_pool);
   if (isDebugEnabled())
     logDebug(fctName, L"Creating new pool \"" + 
static_cast<wstring>(*new_pool) + L"\"");
+  tryTocleanUpPools();
   return *new_pool;
 }
 
 /*static*/
+void ControllerPoolManager::tryTocleanUpPools()
+{
+  const wchar_t fctName[] = L"ControllerPoolManager::tryTocleanUpPools";
+  LockScope ls(&pool_map_CS);
+  for (std::map<PoolIndex, AbstractControllerPool*, ltPoolIndex>::iterator iter
+      = pool_map.begin(); iter != pool_map.end();)
+  {
+    if (iter->second->getRefCount() == 0)
+    {
+      if ((currentTimeMillis() - POOL_TIMEOUT_IN_MS) > 
iter->second->getLastTimeZeroRef())
+      {
+        std::map<PoolIndex, AbstractControllerPool*, ltPoolIndex>::iterator 
toRemove = iter;
+        if (isInfoEnabled())
+          logInfo(fctName, L"Pool \"" + static_cast<wstring>(*toRemove->second)
+              + L"\" freed " + 
toWString(static_cast<int64_t>(currentTimeMillis()-toRemove->second->getLastTimeZeroRef()))
+              + L"ms ago - Deleting it");
+        iter++;
+        delete toRemove->second;
+        pool_map.erase(toRemove);
+      }
+      else
+        iter++;
+    }
+    else
+      iter++;
+  }
+}
+
+/*static*/
 void ControllerPoolManager::freePool(AbstractControllerPool* pool)
 {
   const wchar_t fctName[] = L"ControllerPoolManager::freePool";
@@ -328,24 +358,24 @@
     return;
   }
   LockScope ls(&pool_map_CS);
-  for (std::map<PoolIndex, AbstractControllerPool*, ltPoolIndex>::iterator iter
-      = pool_map.begin(); iter != pool_map.end(); iter++)
+  std::map<PoolIndex, AbstractControllerPool*, ltPoolIndex>::iterator iter = 
pool_map.begin();
+  while (iter != pool_map.end())
   {
     if (iter->second == pool)
     {
-      if (pool->removeRef() == 0)
+      if (iter->second->removeRef() == 0)
       {
         if (isDebugEnabled())
           logDebug(fctName, L"No more references to pool \""
-              + static_cast<wstring>(*pool) + L"\" - deleting it");
-        pool_map.erase(iter); // don't mind about iter, we won't use it anymore
-        delete pool;
+              + static_cast<wstring>(*iter->second) + L"\" - keeping it at 
least "
+              + toWString(POOL_TIMEOUT_IN_MS) + L" ms");
       }
-      return;
+      break; // pool found, stop search
     }
+    iter++;
   }
   // No match => log error and continue
-  if (isErrorEnabled())
+  if (iter == pool_map.end() && isErrorEnabled())
   {
     wstring msg(L"Pool " + static_cast<wstring>(*pool)
         + L" not found in pool map! Map contains ");
@@ -356,4 +386,6 @@
     }
     logError(fctName, msg);
   }
+  // look for pools to delete
+  tryTocleanUpPools();
 }

_______________________________________________
Carob-commits mailing list
[email protected]
https://forge.continuent.org/mailman/listinfo/carob-commits

Reply via email to