From 561995d123f1ee04296cfa2f2aef07ceccb4c617 Mon Sep 17 00:00:00 2001 From: randomdan Date: Mon, 28 Feb 2011 19:22:20 +0000 Subject: Add support for local error handling --- project2/Jamfile.jam | 4 +-- project2/cgi/cgiAppEngine.cpp | 23 +++---------- project2/cgi/cgiAppEngine.h | 5 ++- project2/console/consoleAppEngine.cpp | 20 +++-------- project2/console/consoleAppEngine.h | 5 ++- project2/if.cpp | 21 ++++++++++-- project2/if.h | 3 ++ project2/iterate.cpp | 34 +++++++++++-------- project2/iterate.h | 4 ++- project2/noOutputExecute.h | 7 ++-- project2/requestHost.cpp | 63 +++++++++++++++++++++++++++++++++++ project2/requestHost.h | 31 +++++++++++++++++ 12 files changed, 158 insertions(+), 62 deletions(-) create mode 100644 project2/requestHost.cpp create mode 100644 project2/requestHost.h 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 : ../libmisc//misc 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()) { - 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 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::Objects ParamCheckers; ParamCheckers parameterChecks; - typedef Storage::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()) { - 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 #include #include 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::Objects ParamCheckers; ParamCheckers parameterChecks; - typedef Storage::Objects Tasks; - Tasks tasks; typedef Storage::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()) { - sq->execute(); + try { + BOOST_FOREACH(const SubNOEs::value_type & sq, subNOEs.get()) { + if (!sq->isErrorHandler) { + sq->execute(); + } + } + } + catch (...) { + BOOST_FOREACH(const SubNOEs::value_type & sq, subNOEs.get()) { + 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()) { - if (dynamic_cast(sq.get())) { - sq->execute(); - } - else { - RowSet::beginRow(NULL); - try { + if (sq->isErrorHandler == errs) { + if (dynamic_cast(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::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 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 + +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()) { + 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::Objects Tasks; + typedef Storage::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 + -- cgit v1.2.3