summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrandomdan <randomdan@localhost>2010-10-26 17:28:35 +0000
committerrandomdan <randomdan@localhost>2010-10-26 17:28:35 +0000
commit8d625d0cdba5bd47000efb9eea51cfa7b84ac1cd (patch)
tree7479d8a31c1d228261487c3ee62d3d1e599a1f64
parentRemove useless include to rdbms (diff)
downloadproject2-8d625d0cdba5bd47000efb9eea51cfa7b84ac1cd.tar.bz2
project2-8d625d0cdba5bd47000efb9eea51cfa7b84ac1cd.tar.xz
project2-8d625d0cdba5bd47000efb9eea51cfa7b84ac1cd.zip
Add callbacks for key points in time allow clean up of unused stuff
Use these callbacks to clean up unused DB connections
-rw-r--r--project2/cgi/p2webMain.cpp20
-rw-r--r--project2/console/p2consoleMain.cpp3
-rw-r--r--project2/rdbmsDataSource.cpp35
-rw-r--r--project2/rdbmsDataSource.h11
-rw-r--r--project2/xmlObjectLoader.cpp26
-rw-r--r--project2/xmlObjectLoader.h6
6 files changed, 98 insertions, 3 deletions
diff --git a/project2/cgi/p2webMain.cpp b/project2/cgi/p2webMain.cpp
index d464406..c36335a 100644
--- a/project2/cgi/p2webMain.cpp
+++ b/project2/cgi/p2webMain.cpp
@@ -18,9 +18,22 @@ xmlWrite(void * _out, const char * buf, int len)
return len;
}
+time_t lastPeriodic = 0;
+time_t periodicDelay = 600;
+
+void
+p2webPeriodic()
+{
+ time(&lastPeriodic);
+ LoaderBase::onPeriodic();
+}
+
void
p2webGoingIdle(int)
{
+ if (time(NULL) > lastPeriodic + periodicDelay) {
+ p2webPeriodic();
+ }
LoaderBase::onIdle();
}
@@ -64,6 +77,10 @@ int main(void)
IO << "Kaboom!" << std::endl << std::endl << "Unknown exception.";
}
alarm(60);
+ LoaderBase::onIteration();
+ if (time(NULL) > lastPeriodic + periodicDelay) {
+ p2webPeriodic();
+ }
}
}
else {
@@ -72,6 +89,9 @@ int main(void)
CgiApplicationEngine app(&env);
app.process();
app.write(boost::bind(xmlDocDump, realstdout, _1));
+ LoaderBase::onIteration();
+ LoaderBase::onPeriodic();
+ LoaderBase::onIdle();
}
return 0;
}
diff --git a/project2/console/p2consoleMain.cpp b/project2/console/p2consoleMain.cpp
index 25c06fa..eb3ff0d 100644
--- a/project2/console/p2consoleMain.cpp
+++ b/project2/console/p2consoleMain.cpp
@@ -9,6 +9,9 @@ int main(int argc, char ** argv)
BOOST_FOREACH(const boost::filesystem::path & file, env.todolist) {
ConsoleApplicationEngine app(&env, file);
app.process();
+ LoaderBase::onIteration();
}
+ LoaderBase::onPeriodic();
+ LoaderBase::onIdle();
}
diff --git a/project2/rdbmsDataSource.cpp b/project2/rdbmsDataSource.cpp
index cab37bf..4f9c7d7 100644
--- a/project2/rdbmsDataSource.cpp
+++ b/project2/rdbmsDataSource.cpp
@@ -16,6 +16,18 @@ class RdbmsDataSourceLoader : public ElementLoaderImpl<_RdbmsDataSource> {
// Disconnect all cached database connections
_RdbmsDataSource::dbhosts.clear();
}
+ static bool isConnectionExpired(const _RdbmsDataSource::DBHosts::value_type & con)
+ {
+ return con.second->isExpired();
+ }
+ void onPeriodic()
+ {
+ // Disconnect expired database connections
+ _RdbmsDataSource::DBHosts::iterator i;
+ while ((i = std::find_if(_RdbmsDataSource::dbhosts.begin(), _RdbmsDataSource::dbhosts.end(), isConnectionExpired)) != _RdbmsDataSource::dbhosts.end()) {
+ _RdbmsDataSource::dbhosts.erase(i);
+ }
+ }
} rdbmsLoader;
_RdbmsDataSource::DBHosts _RdbmsDataSource::dbhosts;
@@ -129,6 +141,7 @@ _RdbmsDataSource::connectTo(const std::string & dsn)
try {
SQLINTEGER dead = dbi->second->getAttrInt(SQL_ATTR_CONNECTION_DEAD);
if (dead == SQL_CD_FALSE) {
+ dbi->second->touch();
return dbi->second;
}
}
@@ -139,8 +152,9 @@ _RdbmsDataSource::connectTo(const std::string & dsn)
}
try {
- ConnectionPtr db = ConnectionPtr(new ODBC::Connection(dsn));
+ ConnectionPtr db = ConnectionPtr(new RdbmsConnection(dsn, 300));
dbhosts[dsn] = db;
+ db->touch();
return db;
}
catch (const ODBC::ConnectionError & e) {
@@ -149,3 +163,22 @@ _RdbmsDataSource::connectTo(const std::string & dsn)
}
}
+_RdbmsDataSource::RdbmsConnection::RdbmsConnection(const std::string & dsn, time_t kat) :
+ ODBC::Connection(dsn),
+ lastUsedTime(0),
+ keepAliveTime(kat)
+{
+}
+
+void
+_RdbmsDataSource::RdbmsConnection::touch() const
+{
+ time(&lastUsedTime);
+}
+
+bool
+_RdbmsDataSource::RdbmsConnection::isExpired() const
+{
+ return (time(NULL) > lastUsedTime + keepAliveTime);
+}
+
diff --git a/project2/rdbmsDataSource.h b/project2/rdbmsDataSource.h
index bb1047a..77fbe3a 100644
--- a/project2/rdbmsDataSource.h
+++ b/project2/rdbmsDataSource.h
@@ -9,7 +9,16 @@
class _RdbmsDataSource : public _DataSource {
public:
- typedef boost::shared_ptr<ODBC::Connection> ConnectionPtr;
+ class RdbmsConnection : public ODBC::Connection {
+ public:
+ RdbmsConnection(const std::string & dsn, time_t keepAliveTime);
+ void touch() const;
+ bool isExpired() const;
+ private:
+ mutable time_t lastUsedTime;
+ const time_t keepAliveTime;
+ };
+ typedef boost::shared_ptr<RdbmsConnection> ConnectionPtr;
typedef std::map<std::string, std::string> ReadonlyDSNs; // Map hostname to DSN string
typedef std::map<std::string, ConnectionPtr> DBHosts; // Map DSN strings to connections
typedef std::map<std::string, const ODBC::ConnectionError> FailedHosts; // Map DSN strings to failures
diff --git a/project2/xmlObjectLoader.cpp b/project2/xmlObjectLoader.cpp
index 6934aaf..9b4b24b 100644
--- a/project2/xmlObjectLoader.cpp
+++ b/project2/xmlObjectLoader.cpp
@@ -64,7 +64,33 @@ LoaderBase::onIdle()
}
void
+LoaderBase::onIteration()
+{
+ BOOST_FOREACH(ElementLoaderMap::value_type l, getMap()) {
+ l.second->onIteration();
+ }
+}
+
+void
+LoaderBase::onPeriodic()
+{
+ BOOST_FOREACH(ElementLoaderMap::value_type l, getMap()) {
+ l.second->onPeriodic();
+ }
+}
+
+void
ElementLoader::onIdle()
{
}
+void
+ElementLoader::onIteration()
+{
+}
+
+void
+ElementLoader::onPeriodic()
+{
+}
+
diff --git a/project2/xmlObjectLoader.h b/project2/xmlObjectLoader.h
index d871d9b..56cdfac 100644
--- a/project2/xmlObjectLoader.h
+++ b/project2/xmlObjectLoader.h
@@ -95,6 +95,8 @@ class LoaderBase {
std::set<boost::intrusive_ptr<Storer> > supportedStorers;
static void onIdle();
+ static void onIteration();
+ static void onPeriodic();
private:
static unsigned int depth;
@@ -104,7 +106,9 @@ class LoaderBase {
class ElementLoader {
public:
virtual Project2SourceObject go(const xmlpp::Element * xml) const = 0;
- virtual void onIdle();
+ virtual void onIdle(); // When the app engine goes idle
+ virtual void onIteration(); // When the app engine has completed an iteration
+ virtual void onPeriodic(); // When the app engine feels like it
};
template <class X>