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> | 
