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