From 55376f112a70a734040cf7f038fbef0eb3049ef0 Mon Sep 17 00:00:00 2001 From: randomdan Date: Wed, 25 Aug 2010 19:41:25 +0000 Subject: Add alarm to be called when p2web has been idle for 60seconds Use the new onIdle callback to disconnect all cached database connections --- project2/cgi/p2webMain.cpp | 16 ++++++++++++++++ project2/rdbmsDataSource.cpp | 12 +++++++++++- project2/rdbmsDataSource.h | 2 ++ project2/xmlObjectLoader.cpp | 13 +++++++++++++ project2/xmlObjectLoader.h | 5 ++++- 5 files changed, 46 insertions(+), 2 deletions(-) diff --git a/project2/cgi/p2webMain.cpp b/project2/cgi/p2webMain.cpp index ef070f0..d464406 100644 --- a/project2/cgi/p2webMain.cpp +++ b/project2/cgi/p2webMain.cpp @@ -7,6 +7,7 @@ FILE * realstdout = stdout; #include "cgiEnvironment.h" #include "cgiAppEngine.h" #include +#include #include "FCgiIO.h" int @@ -17,6 +18,12 @@ xmlWrite(void * _out, const char * buf, int len) return len; } +void +p2webGoingIdle(int) +{ + LoaderBase::onIdle(); +} + int main(void) { if (!FCGX_IsCGI()) { @@ -25,7 +32,15 @@ int main(void) FCGX_Init(); FCGX_InitRequest(&request, 0, 0); + struct sigaction onAlarm; + onAlarm.sa_handler = &p2webGoingIdle; + onAlarm.sa_flags = 0; + if (sigaction(SIGALRM, &onAlarm, NULL)) { + syslog(LOG_WARNING, "Failed to set signal handler"); + } + alarm(60); while (FCGX_Accept_r(&request) == 0) { + alarm(0); cgicc::FCgiIO IO(request); try { cgicc::Cgicc cgi(&IO); @@ -48,6 +63,7 @@ int main(void) header.render(IO); IO << "Kaboom!" << std::endl << std::endl << "Unknown exception."; } + alarm(60); } } else { diff --git a/project2/rdbmsDataSource.cpp b/project2/rdbmsDataSource.cpp index ef1c694..cab37bf 100644 --- a/project2/rdbmsDataSource.cpp +++ b/project2/rdbmsDataSource.cpp @@ -6,7 +6,17 @@ #include #include -ElementLoaderImpl<_RdbmsDataSource> rdbmsLoader("rdbmsdatasource"); +class RdbmsDataSourceLoader : public ElementLoaderImpl<_RdbmsDataSource> { + public: + RdbmsDataSourceLoader() : ElementLoaderImpl<_RdbmsDataSource>("rdbmsdatasource") + { + } + void onIdle() + { + // Disconnect all cached database connections + _RdbmsDataSource::dbhosts.clear(); + } +} rdbmsLoader; _RdbmsDataSource::DBHosts _RdbmsDataSource::dbhosts; _RdbmsDataSource::FailedHosts _RdbmsDataSource::failedhosts; diff --git a/project2/rdbmsDataSource.h b/project2/rdbmsDataSource.h index d360529..bb1047a 100644 --- a/project2/rdbmsDataSource.h +++ b/project2/rdbmsDataSource.h @@ -31,6 +31,8 @@ class _RdbmsDataSource : public _DataSource { mutable std::string localhost; static DBHosts dbhosts; static FailedHosts failedhosts; + + friend class RdbmsDataSourceLoader; }; typedef boost::shared_ptr<_RdbmsDataSource> RdbmsDataSource; typedef std::map RdbmsDataSources; diff --git a/project2/xmlObjectLoader.cpp b/project2/xmlObjectLoader.cpp index 71f1b53..6934aaf 100644 --- a/project2/xmlObjectLoader.cpp +++ b/project2/xmlObjectLoader.cpp @@ -55,3 +55,16 @@ LoaderBase::collectAll(const Glib::ustring & ns, const xmlpp::Element * node, bo } } +void +LoaderBase::onIdle() +{ + BOOST_FOREACH(ElementLoaderMap::value_type l, getMap()) { + l.second->onIdle(); + } +} + +void +ElementLoader::onIdle() +{ +} + diff --git a/project2/xmlObjectLoader.h b/project2/xmlObjectLoader.h index 0be5eeb..d871d9b 100644 --- a/project2/xmlObjectLoader.h +++ b/project2/xmlObjectLoader.h @@ -83,7 +83,7 @@ Storer::into(std::map > * map) class LoaderBase { public: - typedef std::map ElementLoaderMap; + typedef std::map ElementLoaderMap; void collectAll(const Glib::ustring & ns, const xmlpp::Element * node, bool recursive, bool childrenOnly) const; static ElementLoaderMap & getMap(); @@ -94,6 +94,8 @@ class LoaderBase { static void save(std::map > * map, boost::intrusive_ptr obj); std::set > supportedStorers; + static void onIdle(); + private: static unsigned int depth; static std::set loadedObjects; @@ -102,6 +104,7 @@ class LoaderBase { class ElementLoader { public: virtual Project2SourceObject go(const xmlpp::Element * xml) const = 0; + virtual void onIdle(); }; template -- cgit v1.2.3