diff options
author | randomdan <randomdan@localhost> | 2010-10-26 17:28:35 +0000 |
---|---|---|
committer | randomdan <randomdan@localhost> | 2010-10-26 17:28:35 +0000 |
commit | 8d625d0cdba5bd47000efb9eea51cfa7b84ac1cd (patch) | |
tree | 7479d8a31c1d228261487c3ee62d3d1e599a1f64 | |
parent | Remove useless include to rdbms (diff) | |
download | project2-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.cpp | 20 | ||||
-rw-r--r-- | project2/console/p2consoleMain.cpp | 3 | ||||
-rw-r--r-- | project2/rdbmsDataSource.cpp | 35 | ||||
-rw-r--r-- | project2/rdbmsDataSource.h | 11 | ||||
-rw-r--r-- | project2/xmlObjectLoader.cpp | 26 | ||||
-rw-r--r-- | project2/xmlObjectLoader.h | 6 |
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> |