diff options
| author | randomdan <randomdan@localhost> | 2011-02-28 19:22:20 +0000 | 
|---|---|---|
| committer | randomdan <randomdan@localhost> | 2011-02-28 19:22:20 +0000 | 
| commit | 561995d123f1ee04296cfa2f2aef07ceccb4c617 (patch) | |
| tree | 4871987d8ae149bef20a3d62c13ea3dd1d2c627d | |
| parent | Add support for a timeout, settable in ms, defaulting to 6000, for xslRows (diff) | |
| download | project2-561995d123f1ee04296cfa2f2aef07ceccb4c617.tar.bz2 project2-561995d123f1ee04296cfa2f2aef07ceccb4c617.tar.xz project2-561995d123f1ee04296cfa2f2aef07ceccb4c617.zip  | |
Add support for local error handling
| -rw-r--r-- | project2/Jamfile.jam | 4 | ||||
| -rw-r--r-- | project2/cgi/cgiAppEngine.cpp | 23 | ||||
| -rw-r--r-- | project2/cgi/cgiAppEngine.h | 5 | ||||
| -rw-r--r-- | project2/console/consoleAppEngine.cpp | 20 | ||||
| -rw-r--r-- | project2/console/consoleAppEngine.h | 5 | ||||
| -rw-r--r-- | project2/if.cpp | 21 | ||||
| -rw-r--r-- | project2/if.h | 3 | ||||
| -rw-r--r-- | project2/iterate.cpp | 34 | ||||
| -rw-r--r-- | project2/iterate.h | 4 | ||||
| -rw-r--r-- | project2/noOutputExecute.h | 7 | ||||
| -rw-r--r-- | project2/requestHost.cpp | 63 | ||||
| -rw-r--r-- | project2/requestHost.h | 31 | 
12 files changed, 158 insertions, 62 deletions
diff --git a/project2/Jamfile.jam b/project2/Jamfile.jam index f591344..4f8ba1a 100644 --- a/project2/Jamfile.jam +++ b/project2/Jamfile.jam @@ -51,8 +51,8 @@ lib p2common :  	appEngine.cpp dataSource.cpp environment.cpp fileStarGlibIoChannel.cpp iHaveParameters.cpp  	iterate.cpp paramChecker.cpp presenter.cpp rawView.cpp logger.cpp if.cpp xmlScriptParser.cpp  	sourceObject.cpp task.cpp variables.cpp variableConvert.cpp view.cpp xmlObjectLoader.cpp exceptions.cpp -	sessionClearTask.cpp session.cpp sessionSetTask.cpp commonObjects.cpp xmlPresenter.cpp -	rowView.cpp rowSet.cpp rowUser.cpp rowProcessor.cpp config.cpp fileStrmVarWriter.cpp +	sessionClearTask.cpp session.cpp sessionSetTask.cpp commonObjects.cpp xmlPresenter.cpp requestHost.cpp +	rowView.cpp rowSet.cpp rowUser.cpp rowProcessor.cpp config.cpp fileStrmVarWriter.cpp noOutputExecute.cpp  	:  	<library>../libmisc//misc  	<library>libxmlpp diff --git a/project2/cgi/cgiAppEngine.cpp b/project2/cgi/cgiAppEngine.cpp index 043da76..9f7665d 100644 --- a/project2/cgi/cgiAppEngine.cpp +++ b/project2/cgi/cgiAppEngine.cpp @@ -97,6 +97,7 @@ CgiApplicationEngine::write(std::ostream & IO) const  	xmlOutputBufferPtr out = xmlOutputBufferCreateIO(  			xmlWrite, NULL, &IO, xmlGetCharEncodingHandler(XML_CHAR_ENCODING_UTF8));  	xmlSaveFileTo(out, currentStage->getDataDocument()->cobj(), "utf-8"); +	sessionsContainer->CleanUp();  #ifndef NDEBUG  	if (!_env->dumpdatadoc.empty()) {  		currentStage->getDataDocument()->write_to_file_formatted(_env->dumpdatadoc); @@ -146,7 +147,6 @@ CgiApplicationEngine::PresentStage::run()  		}  	}  	execute(); -	sessionsContainer->CleanUp();  	return NULL;  } @@ -204,6 +204,8 @@ CgiApplicationEngine::RequestStage::RequestStage(const std::string & id)  	XmlScriptParser request("request", id, false);  	xmlpp::Element * requestRoot = request.get_document()->get_root_node();  	present = requestRoot->get_attribute_value("present"); +	rollbackBeforeHandle = requestRoot->get_attribute_value("rollbackBeforeHandle") == "true"; +	localErrorHandling = requestRoot->get_attribute_value("errorHandling") == "local";  	LoaderBase loader("http://project2.randomdan.homeip.net", true);  	loader.supportedStorers.insert(Storer::into(¶meterChecks)); @@ -222,23 +224,8 @@ CgiApplicationEngine::RequestStage::run()  			return new PresentStage(pc->present);  		}  	} -	try { -		BOOST_FOREACH(const Tasks::value_type & t, tasks.get<bySOOrder>()) { -			t->execute(); -		} -		// Commit data source transactions (without invoking a connection) -		BOOST_FOREACH(const DataSources::value_type & ds, datasources) { -			ds->commit(); -		} -		return present.empty() ? NULL : new PresentStage(present); -	} -	catch (...) { -		// Do something about the error -		BOOST_FOREACH(const DataSources::value_type & ds, datasources) { -			ds->rollback(); -		} -		throw; -	} +	RequestHost::run(); +	return present.empty() ? NULL : new PresentStage(present);  }  CgiApplicationEngine::HttpHeaderPtr diff --git a/project2/cgi/cgiAppEngine.h b/project2/cgi/cgiAppEngine.h index 79638f4..65142b6 100644 --- a/project2/cgi/cgiAppEngine.h +++ b/project2/cgi/cgiAppEngine.h @@ -7,6 +7,7 @@  #include "../xmlPresenter.h"  #include "../commonObjects.h"  #include "../uuid.h" +#include "../requestHost.h"  #include <boost/intrusive_ptr.hpp>  class CgiEnvironment; @@ -52,7 +53,7 @@ class CgiApplicationEngine : public ApplicationEngine {  				virtual HttpHeaderPtr getHeader() const = 0;  		}; -		class RequestStage : public Stage, public XmlPresenter { +		class RequestStage : public Stage, public XmlPresenter, RequestHost {  			public:  				RequestStage(const std::string & id);  				virtual ~RequestStage(); @@ -67,8 +68,6 @@ class CgiApplicationEngine : public ApplicationEngine {  				std::string present;  				typedef Storage<ParamChecker>::Objects ParamCheckers;  				ParamCheckers parameterChecks; -				typedef Storage<NoOutputExecute>::Objects Tasks; -				Tasks tasks;  			private:  				static const Glib::ustring resp; diff --git a/project2/console/consoleAppEngine.cpp b/project2/console/consoleAppEngine.cpp index e126793..eed37fd 100644 --- a/project2/console/consoleAppEngine.cpp +++ b/project2/console/consoleAppEngine.cpp @@ -59,6 +59,9 @@ ConsoleApplicationEngine::ConsoleApplicationEngine(const ConsoleEnvironment * en  	out(stdout, true)  {  	XmlScriptParser request(f.string(), false); +	xmlpp::Element * requestRoot = request.get_document()->get_root_node(); +	rollbackBeforeHandle = requestRoot->get_attribute_value("rollbackBeforeHandle") == "true"; +	localErrorHandling = requestRoot->get_attribute_value("errorHandling") == "local";  	LoaderBase loader("http://project2.randomdan.homeip.net", true);  	loader.supportedStorers.insert(Storer::into(¶meterChecks)); @@ -80,22 +83,7 @@ ConsoleApplicationEngine::process() const  			throw std::runtime_error("Check failed");  		}  	} -	try { -		BOOST_FOREACH(const Tasks::value_type & t, tasks.get<bySOOrder>()) { -			t->execute(); -		} -		// Commit data source transactions (without invoking a connection) -		BOOST_FOREACH(const DataSources::value_type & ds, this->datasources) { -			ds->commit(); -		} -	} -	catch (...) { -		// Do something about the error -		BOOST_FOREACH(const DataSources::value_type & ds, this->datasources) { -			ds->rollback(); -		} -		throw; -	} +	RequestHost::run();  	BOOST_FOREACH(const Views::value_type & v, views) {  		v->execute(this);  	} diff --git a/project2/console/consoleAppEngine.h b/project2/console/consoleAppEngine.h index d8cdca5..1e4f1c3 100644 --- a/project2/console/consoleAppEngine.h +++ b/project2/console/consoleAppEngine.h @@ -8,13 +8,14 @@  #include "../commonObjects.h"  #include "../view.h"  #include "../fileStrmVarWriter.h" +#include "../requestHost.h"  #include <boost/intrusive_ptr.hpp>  #include <boost/filesystem/path.hpp>  #include <libxml++/document.h>  class ConsoleEnvironment; -class ConsoleApplicationEngine : public ApplicationEngine, public Presenter { +class ConsoleApplicationEngine : public ApplicationEngine, public Presenter, RequestHost {  	public:  		ConsoleApplicationEngine(const ConsoleEnvironment *, const boost::filesystem::path &);  		virtual ~ConsoleApplicationEngine(); @@ -46,8 +47,6 @@ class ConsoleApplicationEngine : public ApplicationEngine, public Presenter {  		typedef Storage<ParamChecker>::Objects ParamCheckers;  		ParamCheckers parameterChecks; -		typedef Storage<NoOutputExecute>::Objects Tasks; -		Tasks tasks;  		typedef Storage<View>::Objects Views;  		Views views;  		SessionPtr runtime; diff --git a/project2/if.cpp b/project2/if.cpp index fe47059..a69fd8d 100644 --- a/project2/if.cpp +++ b/project2/if.cpp @@ -41,7 +41,8 @@ If::If(const xmlpp::Element * e) :  	SourceObject(e),  	Iterate(e),  	RowView(e), -	IfSet(e) +	IfSet(e), +	localErrorHandling(e->get_attribute_value("errorHandling") == "local")  {  } @@ -66,8 +67,22 @@ If::execute() const  {  	if (passes()) {  		Logger()->message(LOG_DEBUG, "IfSet passed"); -		BOOST_FOREACH(const SubNOEs::value_type & sq, subNOEs.get<bySOOrder>()) { -			sq->execute(); +		try { +			BOOST_FOREACH(const SubNOEs::value_type & sq, subNOEs.get<bySOOrder>()) { +				if (!sq->isErrorHandler) { +					sq->execute(); +				} +			} +		} +		catch (...) { +			BOOST_FOREACH(const SubNOEs::value_type & sq, subNOEs.get<bySOOrder>()) { +				if (sq->isErrorHandler) { +					sq->execute(); +				} +			} +			if (!localErrorHandling) { +				throw; +			}  		}  	}  } diff --git a/project2/if.h b/project2/if.h index 87fc1ee..68f6595 100644 --- a/project2/if.h +++ b/project2/if.h @@ -25,6 +25,9 @@ class If : public Iterate, public RowView, public IfSet {  		virtual void loadComplete(const CommonObjects*);  		virtual void execute(const Presenter*) const;  		virtual void execute() const; + +		const bool localErrorHandling; +  	private:  		const std::string & getName() const;  }; diff --git a/project2/iterate.cpp b/project2/iterate.cpp index f0097c8..ccf289e 100644 --- a/project2/iterate.cpp +++ b/project2/iterate.cpp @@ -7,7 +7,8 @@ DECLARE_LOADER("iterate", Iterate);  Iterate::Iterate(const xmlpp::Element * p) :  	SourceObject(p),  	NoOutputExecute(p), -	RowProcessor(p) +	RowProcessor(p), +	localErrorHandling(p->get_attribute_value("errorHandling") == "local")  {  	LoaderBase loader("http://project2.randomdan.homeip.net", true);  	loader.supportedStorers.insert(Storer::into(&subNOEs)); @@ -27,7 +28,7 @@ Iterate::loadComplete(const CommonObjects * co)  void  Iterate::rowReady() const  { -	executeChildren(); +	executeChildren(false);  	source->rowChanged();  } @@ -44,26 +45,31 @@ Iterate::execute() const  	}  	catch (...) {  		RowSet::endRow(source.get()); -		throw; +		executeChildren(true); +		if (!localErrorHandling) { +			throw; +		}  	}  }  void -Iterate::executeChildren() const +Iterate::executeChildren(bool errs) const  {  	BOOST_FOREACH(const SubNOEs::value_type & sq, subNOEs.get<bySOOrder>()) { -		if (dynamic_cast<const RowProcessor *>(sq.get())) { -			sq->execute(); -		} -		else { -			RowSet::beginRow(NULL); -			try { +		if (sq->isErrorHandler == errs) { +			if (dynamic_cast<const RowProcessor *>(sq.get())) {  				sq->execute(); -				RowSet::endRow(NULL);  			} -			catch (...) { -				RowSet::endRow(NULL); -				throw; +			else { +				RowSet::beginRow(NULL); +				try { +					sq->execute(); +					RowSet::endRow(NULL); +				} +				catch (...) { +					RowSet::endRow(NULL); +					throw; +				}  			}  		}  	} diff --git a/project2/iterate.h b/project2/iterate.h index 2c7eeba..d5ca824 100644 --- a/project2/iterate.h +++ b/project2/iterate.h @@ -21,8 +21,10 @@ class Iterate : public NoOutputExecute, public RowProcessor {  		typedef Storage<NoOutputExecute>::Objects SubNOEs;  		SubNOEs subNOEs; +		const bool localErrorHandling; +  	protected: -		void executeChildren() const; +		void executeChildren(bool errs) const;  };  #endif diff --git a/project2/noOutputExecute.h b/project2/noOutputExecute.h index ec73ce1..f47c118 100644 --- a/project2/noOutputExecute.h +++ b/project2/noOutputExecute.h @@ -11,10 +11,13 @@ typedef boost::intrusive_ptr<NoOutputExecute> NoOutputExecutePtr;  class NoOutputExecute : public virtual SourceObject {  	public: -		NoOutputExecute(const xmlpp::Element * p) : SourceObject(p) { }; -		NoOutputExecute(const std::string & n) : SourceObject(n) { }; +		NoOutputExecute(const xmlpp::Element * p); +		NoOutputExecute(const std::string & n);  		virtual ~NoOutputExecute() { } +  		virtual void execute() const = 0; + +		const bool isErrorHandler;  };  #endif diff --git a/project2/requestHost.cpp b/project2/requestHost.cpp new file mode 100644 index 0000000..09de71f --- /dev/null +++ b/project2/requestHost.cpp @@ -0,0 +1,63 @@ +#include "requestHost.h" +#include "noOutputExecute.h" +#include "dataSource.h" +#include <boost/foreach.hpp> + +RequestHost::RequestHost() +{ +} + +RequestHost::~RequestHost() +{ +} + +void +RequestHost::run() const +{ +	try { +		run(false); +		commitAll(); +	} +	catch (...) { +		if (rollbackBeforeHandle) { +			rollbackAll(); +		} +		try { +			run(true); +			commitAll(); +		} +		catch (...) { +			rollbackAll(); +		} +		if (!localErrorHandling) { +			throw; +		} +	} +} + +void +RequestHost::run(bool errs) const +{ +	BOOST_FOREACH(const Tasks::value_type & t, tasks.get<bySOOrder>()) { +		if (t->isErrorHandler == errs) { +			t->execute(); +		} +	} +} + +void +RequestHost::commitAll() const +{ +	BOOST_FOREACH(const DataSources::value_type & ds, datasources) { +		ds->commit(); +	} +} + +void +RequestHost::rollbackAll() const +{ +	BOOST_FOREACH(const DataSources::value_type & ds, datasources) { +		ds->rollback(); +	} +} + diff --git a/project2/requestHost.h b/project2/requestHost.h new file mode 100644 index 0000000..7610ac1 --- /dev/null +++ b/project2/requestHost.h @@ -0,0 +1,31 @@ +#ifndef REQUEST_HOST_H +#define REQUEST_HOST_H + +#include "xmlStorage.h" +#include "commonObjects.h" + +class NoOutputExecute; +class DataSource; + +class RequestHost : virtual CommonObjects { +	protected: +		typedef Storage<NoOutputExecute>::Objects Tasks; +		typedef Storage<DataSource>::Objects DataSources; + +		RequestHost(); +		virtual ~RequestHost() = 0; + +		void run() const; + +		Tasks tasks; +		bool rollbackBeforeHandle; +		bool localErrorHandling; + +	private: +		void commitAll() const; +		void rollbackAll() const; +		void run(bool errs) const; +}; + +#endif +  | 
