Date: Wednesday, February 7, 2007 @ 16:32:33
  Author: gilles
    Path: /cvsroot/carob/carob

Modified: include/Common.hpp (1.58 -> 1.59) include/ControllerPool.hpp
          (1.12 -> 1.13) include/WatchedControllers.hpp (1.5 -> 1.6)
          src/Common.cpp (1.67 -> 1.68) src/Connection.cpp (1.110 ->
          1.111) src/ControllerPingSender.cpp (1.7 -> 1.8)
          src/ControllerPool.cpp (1.19 -> 1.20) src/ControllerWatcher.cpp
          (1.14 -> 1.15) src/WatchedControllers.cpp (1.6 -> 1.7)

Final fix for CAROB-119: handling of vdb states for reconnections.
Now, the ControllerAndVdbState class carries the last time the vdb was down on
a controller. If this vdb has been down for less than 5 secs, don't give this
controller for connections.

Renamed getCurrentTimeInMs() to currentTimeMillis() to stick to java naming,
changed return type from long to int64_t to avoid overflows
Introduced currentTimeSeconds() functions for vdb states (where we don't need 
millis)

Fixed memory leaks upon reconnection (driver socket was not deleted)


--------------------------------+
 include/Common.hpp             |    7 ++-
 include/ControllerPool.hpp     |   55 ++++++++++++++++++++++++++++
 include/WatchedControllers.hpp |   18 ++++-----
 src/Common.cpp                 |   16 +++++++-
 src/Connection.cpp             |    8 +++-
 src/ControllerPingSender.cpp   |    4 +-
 src/ControllerPool.cpp         |   74 +++++++++++++++++++++++++++++++++++----
 src/ControllerWatcher.cpp      |    6 +--
 src/WatchedControllers.cpp     |   10 ++---
 9 files changed, 166 insertions(+), 32 deletions(-)


Index: carob/include/Common.hpp
diff -u carob/include/Common.hpp:1.58 carob/include/Common.hpp:1.59
--- carob/include/Common.hpp:1.58       Wed Jan 31 11:45:10 2007
+++ carob/include/Common.hpp    Wed Feb  7 16:32:33 2007
@@ -242,8 +242,11 @@
 /**
  * Utility to get the current time as number of ms since Epoch
  */
-long getCurrentTimeInMs();
-
+int64_t currentTimeMillis();
+/**
+ * Same as above, in seconds
+ */
+int currentTimeSeconds();
 } //namespace CarobNS
 #endif //_COMMON_H_
 
Index: carob/include/ControllerPool.hpp
diff -u carob/include/ControllerPool.hpp:1.12 
carob/include/ControllerPool.hpp:1.13
--- carob/include/ControllerPool.hpp:1.12       Wed Dec 20 17:32:49 2006
+++ carob/include/ControllerPool.hpp    Wed Feb  7 16:32:33 2007
@@ -24,6 +24,7 @@
 #include "ControllerInfo.hpp"
 #include "CarobException.hpp"
 #include "CriticalSection.hpp"
+#include "Common.hpp" // for currentTimeInSeconds()
 #include <vector>
 #include <map>
 
@@ -53,6 +54,42 @@
 class ControllerWatcher;
 class SocketKillerCallback;
 class JavaSocket;
+
+/** Holds a controller and its last vdb failure */
+class ControllerAndVdbState
+{
+public:
+  /**
+   * Constructs a <code>ControllerAndVdbState</code> object with the given
+   * controller, considering last vdb failure is now minus 60 seconds (ie. no
+   * failure)
+   *
+   * @param ctrl controller to refer to
+   */
+  ControllerAndVdbState(const ControllerInfo& ctrl) : controller(ctrl),
+      lastVdbFailure(currentTimeSeconds() - 60) {};
+  /**
+   * Gives the state of the vdb. Returns true if the last vdb failure is older
+   * than 5 seconds (refering to given time), false if the vdb failed during
+   * the last 5 seconds
+   * 
+   * @param now the time to compare last vdb failure to
+   * @return tru is the vdb can be considered as up, false otherwise
+   */
+  bool            isVdbUp(int now) { return ((now - 5) > lastVdbFailure); }
+
+  /**
+   * Gives a string representation of this object: prints controller + state
+   */
+  operator        std::wstring() { return 
static_cast<std::wstring>(controller) + L" ("
+                      + (isVdbUp(currentTimeSeconds()) ? L"VDB up)" : L"VDB 
down)"); }
+  /** Controller */
+  ControllerInfo  controller;
+  /** Last time the vdb was failing, 0 indicates never */
+  int             lastVdbFailure;
+
+};
+
 /**
  * Abstract class over each policy implementation, which is used by the driver
  * to choose a controller to connect to.
@@ -61,6 +98,7 @@
 {
   // to provide access to add/removeRef()
   friend class ControllerPoolManager;
+
 public:
   /**
    * Unique constructor
@@ -140,6 +178,21 @@
   void                        controllerUp(const ControllerInfo& controller);
 
   /**
+   * Informs that the given controller's vdb is no more available
+   * @param controller the controller set vdb to down
+   */
+  void                        setVdbDownOnController(const ControllerInfo& 
controller);
+
+  /**
+   * Tells if the given controller VDB is available.<br>
+   * 
+   * @param controller the controller to check for vdb state
+   * @return false if the lastVdbFailure associated to the given controller is
+   *         not older than ??? milliseconds, true otherwise
+   */
+  bool                        isVdbUpOnController(const ControllerInfo& 
controller);
+
+  /**
    * Gets a reference to the lock object used in this class
    * @see void Connection::initConnection() 
    */
@@ -160,7 +213,7 @@
    */
   int                         removeRef() { ref_counter--; return ref_counter; 
}
   /** Up-to-date list of controllers that respond to pings */
-  std::vector<ControllerInfo> alive_controllers;
+  std::vector<ControllerAndVdbState> alive_controllers;
   /** Mutex on alive controllers */
   CriticalSection             pool_CS;
 private:
Index: carob/include/WatchedControllers.hpp
diff -u carob/include/WatchedControllers.hpp:1.5 
carob/include/WatchedControllers.hpp:1.6
--- carob/include/WatchedControllers.hpp:1.5    Fri Dec 22 11:21:07 2006
+++ carob/include/WatchedControllers.hpp        Wed Feb  7 16:32:33 2007
@@ -52,16 +52,16 @@
   public:
     ControllerAndState();
     ControllerAndState(const ControllerInfo& ctrl);
-    ControllerAndState(const ControllerInfo& ctrl, long initTime);
+    ControllerAndState(const ControllerInfo& ctrl, int64_t initTime);
     ControllerAndState(const ControllerAndState& src);
 
     ControllerAndState&   operator = (const ControllerAndState& src);
 
-    void                  updateTime(long newTime) { last_time_seen = newTime; 
}
+    void                  updateTime(int64_t newTime) { last_time_seen = 
newTime; }
 
     bool                  isUp() const { return responds_to_pings; }
 
-    long                  getLastTimeSeen() const { return last_time_seen; }
+    int64_t               getLastTimeSeen() const { return last_time_seen; }
 
     void                  setUp() { responds_to_pings = true; }
 
@@ -71,7 +71,7 @@
   private:
     ControllerInfo        controller;
     bool                  responds_to_pings;
-    long                  last_time_seen;
+    int64_t               last_time_seen;
   };
 
 public:
@@ -87,7 +87,7 @@
    * @param cbPtr Callback implementation to call when a controller state
    *          changes
    */
-  WatchedControllers(const std::vector<ControllerInfo>& controllersPrm, long 
initTime,
+  WatchedControllers(const std::vector<ControllerInfo>& controllersPrm, 
int64_t initTime,
       int controllerTimeout, ControllerStateChangedCallback* cbPtr);
 
   /**
@@ -99,12 +99,12 @@
    * Adds a controller to the list and associates the given lastTimeSeenValue 
to
    * it. Note that this operation is thread-safe, thus can slow-down other
    * concurrent operations like [EMAIL PROTECTED] #removeController(const 
ControllerInfo&)},
-   * [EMAIL PROTECTED] #setControllerResponsed(const SocketAddress&, long)}
+   * [EMAIL PROTECTED] #setControllerResponsed(const SocketAddress&, int64_t)}
    * @param ctrl controller to be added
    * @param lastTimeSeen initial time to associate to this controller. 
Typically
    * the result of gettimeofday()
    */
-  void addController(const ControllerInfo& ctrl, long lastTimeSeen);
+  void addController(const ControllerInfo& ctrl, int64_t lastTimeSeen);
 
   /** Removes the selected controller and its associated lastTimeSeen */
   void removeController(const ControllerInfo& ctrl);
@@ -119,7 +119,7 @@
    * 
    * @see ControllerStateChangedCallback
    */
-  void setControllerResponsed(const SocketAddress& ctrlAddr, long newTime);
+  void setControllerResponsed(const SocketAddress& ctrlAddr, int64_t newTime);
 
   /**
    * Updates all controllers state according to the given time.<br>
@@ -132,7 +132,7 @@
    * @param currentTime reference time to compare to last time seen values.
    * Typically the result of gettimeofday()
    */
-  void lookForDeadControllers(long currentTime);
+  void lookForDeadControllers(int64_t currentTime);
 
   /**
    * Forces the given controller to be considered as down.<br>
Index: carob/src/Common.cpp
diff -u carob/src/Common.cpp:1.67 carob/src/Common.cpp:1.68
--- carob/src/Common.cpp:1.67   Wed Jan 31 11:45:10 2007
+++ carob/src/Common.cpp        Wed Feb  7 16:32:33 2007
@@ -307,7 +307,7 @@
   return src;
 }
 
-long CarobNS::getCurrentTimeInMs()
+int64_t CarobNS::currentTimeMillis()
 {
   struct timeval now;
   struct timezone ignored;
@@ -320,6 +320,20 @@
   return now.tv_sec*1000 + now.tv_usec/1000;
 }
 
+
+int CarobNS::currentTimeSeconds()
+{
+  struct timeval now;
+  struct timezone ignored;
+  if (gettimeofday(&now, &ignored) != 0)
+  {
+    if (isErrorEnabled())
+      logError(L"getCurrentTimeInMs", L"gettimeofday failed!");
+    return -1;
+  }
+  return now.tv_sec;
+}
+
 /*
  * Local Variables:
  * c-file-style: "bsd"
Index: carob/src/Connection.cpp
diff -u carob/src/Connection.cpp:1.110 carob/src/Connection.cpp:1.111
--- carob/src/Connection.cpp:1.110      Tue Feb  6 19:53:07 2007
+++ carob/src/Connection.cpp    Wed Feb  7 16:32:33 2007
@@ -230,6 +230,7 @@
       logError(fctName, msg);
     //suspect failing controller
     controller_pool.forceControllerDown(connected_controller);
+    delete driverSocketPtr; driverSocketPtr = NULL;
     // Recurse until no more controller
     connectToNextController();
   }
@@ -240,13 +241,16 @@
       logError(fctName, msg);
     //suspect failing controller
     controller_pool.forceControllerDown(connected_controller);
+    delete driverSocketPtr; driverSocketPtr = NULL;
     // Recurse until no more controller
     connectToNextController();
   }
   catch (VirtualDatabaseUnavailableException vdbue)
   {
-//TODO:
-//    controller_pool.setVdbDownOnController(newController);
+    if (isInfoEnabled())
+      logInfo(fctName, L"Virtual database down on controller " + 
static_cast<wstring>(connected_controller));
+    delete driverSocketPtr; driverSocketPtr = NULL;
+    controller_pool.setVdbDownOnController(connected_controller);
     throw;
   }
 }
Index: carob/src/ControllerPingSender.cpp
diff -u carob/src/ControllerPingSender.cpp:1.7 
carob/src/ControllerPingSender.cpp:1.8
--- carob/src/ControllerPingSender.cpp:1.7      Thu Jan 25 16:10:52 2007
+++ carob/src/ControllerPingSender.cpp  Wed Feb  7 16:32:33 2007
@@ -69,9 +69,9 @@
       // This is really too much logs...
     }
     // detect violent clock changes (user hardly set new date/time)
-    long before = getCurrentTimeInMs();
+    int64_t before = currentTimeMillis();
     usleep((ping_delay_in_ms)*1000);
-    long after = getCurrentTimeInMs();
+    int64_t after = currentTimeMillis();
     int diffMs = static_cast<int>(after-before);
     // usleep calls last at about 10ms. Don't report error on very short 
delays  
     if (diffMs > max_sleep_shift && ping_delay_in_ms>10)
Index: carob/src/ControllerPool.cpp
diff -u carob/src/ControllerPool.cpp:1.19 carob/src/ControllerPool.cpp:1.20
--- carob/src/ControllerPool.cpp:1.19   Thu Jan 25 16:10:52 2007
+++ carob/src/ControllerPool.cpp        Wed Feb  7 16:32:33 2007
@@ -55,7 +55,7 @@
   for (vector<ControllerInfo>::const_iterator iter = controllerList.begin();
       iter != controllerList.end(); iter++)
   {
-    alive_controllers.push_back(*iter);
+    alive_controllers.push_back(ControllerAndVdbState(*iter));
   }
 
   // Create the objects for controller watcher
@@ -85,6 +85,34 @@
   alive_controllers.clear();
 }
 
+void AbstractControllerPool::setVdbDownOnController(const ControllerInfo& 
controller)
+{
+  LockScope ls(&pool_CS);
+  // remove all occurences of the given controller
+  for (vector<ControllerAndVdbState>::iterator iter = 
alive_controllers.begin();
+      iter != alive_controllers.end();)
+  {
+    if (iter->controller == controller)
+    {
+      iter->lastVdbFailure = currentTimeSeconds();
+      return;
+    }
+  }
+}
+
+bool AbstractControllerPool::isVdbUpOnController(const ControllerInfo& 
controller)
+{
+  LockScope ls(&pool_CS);
+  // remove all occurences of the given controller
+  for (vector<ControllerAndVdbState>::iterator iter = 
alive_controllers.begin();
+      iter != alive_controllers.end();)
+  {
+    if (iter->controller == controller)
+      return iter->isVdbUp(currentTimeSeconds());
+  }
+  return false;
+}
+
 int AbstractControllerPool::numberOfAliveControllers()
 {
   LockScope ls(&pool_CS);
@@ -115,10 +143,10 @@
 {
   LockScope ls(&pool_CS);
   // remove all occurences of the given controller
-  for (vector<ControllerInfo>::iterator iter = alive_controllers.begin();
+  for (vector<ControllerAndVdbState>::iterator iter = 
alive_controllers.begin();
       iter != alive_controllers.end();)
   {
-    if (*iter == controller)
+    if (iter->controller == controller)
       iter = alive_controllers.erase(iter);
     else
       iter++;
@@ -128,7 +156,7 @@
 void AbstractControllerPool::controllerUp(const ControllerInfo& controller)
 {
   LockScope ls(&pool_CS);
-  alive_controllers.push_back(controller);
+  alive_controllers.push_back(ControllerAndVdbState(controller));
 }
 
 AbstractControllerPool::operator wstring()
@@ -154,19 +182,51 @@
 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())
+/*  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];
+  return alive_controllers[index].controller;
+*/
+  int nbOfControllers = alive_controllers.size();
+  if (nbOfControllers == 0)
+    throw NoMoreControllerException(L"All controllers down");
+  index++;
+  if (index >= nbOfControllers)
+    index = 0;
+  // to stop iteration when all controllers have been tested
+  int nbTested = 0;
+  // if the vdb was not available for the whished controller, we get the next
+  // one in a round robin manner
+  ControllerAndVdbState ctrl = alive_controllers[index];
+  while (nbTested < nbOfControllers)
+  {
+    if (ctrl.isVdbUp(currentTimeSeconds()))
+    {
+      if (isDebugEnabled())
+        logDebug(fctName, L"Selected controller[" + toUserString(index) + L"]:"
+            + static_cast<wstring>(alive_controllers[index]));
+      return ctrl.controller;
+    }
+    // try next controller
+    index++;
+    if (index >= nbOfControllers)
+      index = 0;
+    nbTested++;
+cout<<"index = "<<index<<endl;
+    ctrl = alive_controllers[index];
+  }
+  // all controllers tested, no more available
+  throw NoMoreControllerException(L"All controllers down");
 }
 
 
////////////////////////////////////////////////////////////////////////////////
Index: carob/src/ControllerWatcher.cpp
diff -u carob/src/ControllerWatcher.cpp:1.14 
carob/src/ControllerWatcher.cpp:1.15
--- carob/src/ControllerWatcher.cpp:1.14        Thu Jan 25 16:10:52 2007
+++ carob/src/ControllerWatcher.cpp     Wed Feb  7 16:32:33 2007
@@ -65,7 +65,7 @@
 {
   const wchar_t fctName[] = L"ControllerWatcher::ControllerWatcher";
 
-  controllers_ptr = new WatchedControllers(controllerList, 
getCurrentTimeInMs(),
+  controllers_ptr = new WatchedControllers(controllerList, currentTimeMillis(),
       controllerTimeout, callbackPtr);
 
   // Get the ip family of the first controller, this will be the default one
@@ -147,7 +147,7 @@
 //        logDebug(fctName, L"Received response from " + 
static_cast<wstring>(ctrl));
       if (buf[0] == CONTROLLER_PING_VERSION)
       {
-        controllers_ptr->setControllerResponsed(ctrlAddr, 
getCurrentTimeInMs());
+        controllers_ptr->setControllerResponsed(ctrlAddr, currentTimeMillis());
       }
       else if (isDebugEnabled())
       {
@@ -195,7 +195,7 @@
       processAnswers();
     }
     // This will start callbacks according to new states
-    controllers_ptr->lookForDeadControllers(getCurrentTimeInMs());
+    controllers_ptr->lookForDeadControllers(currentTimeMillis());
   }
 }
 
Index: carob/src/WatchedControllers.cpp
diff -u carob/src/WatchedControllers.cpp:1.6 
carob/src/WatchedControllers.cpp:1.7
--- carob/src/WatchedControllers.cpp:1.6        Thu Jan 25 16:10:52 2007
+++ carob/src/WatchedControllers.cpp    Wed Feb  7 16:32:33 2007
@@ -41,7 +41,7 @@
 {
 }
 
-WatchedControllers::ControllerAndState::ControllerAndState(const 
ControllerInfo& ctrl, long initTime) :
+WatchedControllers::ControllerAndState::ControllerAndState(const 
ControllerInfo& ctrl, int64_t initTime) :
     controller(ctrl), responds_to_pings(true), last_time_seen(initTime)
 {
 }
@@ -62,7 +62,7 @@
 /* init static member critical section */
 CriticalSection WatchedControllers::controllers_CS;
 WatchedControllers::WatchedControllers(const vector<ControllerInfo>& 
controllersPrm,
-    long initTime, int controllerTimeout, ControllerStateChangedCallback* 
cbPtr) :
+    int64_t initTime, int controllerTimeout, ControllerStateChangedCallback* 
cbPtr) :
     controller_timeout(controllerTimeout),
     callback_ptr(cbPtr)
 {
@@ -81,7 +81,7 @@
   delete callback_ptr;
 }
 
-void WatchedControllers::addController(const ControllerInfo& ctrl, long 
lastTimeSeen)
+void WatchedControllers::addController(const ControllerInfo& ctrl, int64_t 
lastTimeSeen)
 {
   LockScope ls(&controllers_CS);
   ControllerAndState cs(ctrl, lastTimeSeen);
@@ -94,7 +94,7 @@
   controllers.erase(ctrl.getSocketAddress());
 }
 
-void WatchedControllers::setControllerResponsed(const SocketAddress& ctrlAddr, 
long newTime)
+void WatchedControllers::setControllerResponsed(const SocketAddress& ctrlAddr, 
int64_t newTime)
 {
   const wchar_t fctName[] = L"WatchedControllers::setControllerResponsed";
   LockScope ls(&controllers_CS);
@@ -112,7 +112,7 @@
   }
 }
 
-void WatchedControllers::lookForDeadControllers(long currentTime)
+void WatchedControllers::lookForDeadControllers(int64_t currentTime)
 {
   const wchar_t fctName[] = L"WatchedControllers::lookForDeadControllers";
   LockScope ls(&controllers_CS);

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

Reply via email to