diff options
author | randomdan <randomdan@localhost> | 2012-02-12 14:39:28 +0000 |
---|---|---|
committer | randomdan <randomdan@localhost> | 2012-02-12 14:39:28 +0000 |
commit | 722901e3922cda2e53707c84700a309a99ff9d55 (patch) | |
tree | debeb5af1f05909003f8a8ace816f4578e5af587 /project2/cgi | |
parent | Add some more aggregates (diff) | |
download | project2-722901e3922cda2e53707c84700a309a99ff9d55.tar.bz2 project2-722901e3922cda2e53707c84700a309a99ff9d55.tar.xz project2-722901e3922cda2e53707c84700a309a99ff9d55.zip |
Adds support for presenter level caching modules and implements a file based one (requires xattr support)
Diffstat (limited to 'project2/cgi')
-rw-r--r-- | project2/cgi/cgiAppEngine.cpp | 51 | ||||
-rw-r--r-- | project2/cgi/cgiAppEngine.h | 16 | ||||
-rw-r--r-- | project2/cgi/cgiEnvironment.cpp | 6 | ||||
-rw-r--r-- | project2/cgi/cgiEnvironment.h | 1 | ||||
-rw-r--r-- | project2/cgi/cgiStageCacheHit.cpp | 27 | ||||
-rw-r--r-- | project2/cgi/cgiStagePresent.cpp | 12 |
6 files changed, 96 insertions, 17 deletions
diff --git a/project2/cgi/cgiAppEngine.cpp b/project2/cgi/cgiAppEngine.cpp index b92095c..9e91800 100644 --- a/project2/cgi/cgiAppEngine.cpp +++ b/project2/cgi/cgiAppEngine.cpp @@ -27,7 +27,8 @@ getSessionID(const std::vector<cgicc::HTTPCookie> & cookies) { CgiApplicationEngine::CgiApplicationEngine(const CgiEnvironment * e, std::ostream & io) : _env(e), sessionsContainer(LoaderBase::getLoader<SessionContainerLoader, NotSupported>(e->sessionModule)->open()), - IO(io) + IO(io), + outputCachingActive(false) { cursession = sessionsContainer->GetSession(getSessionID(e->getCookieList())); currentStage = NextStage(new InitialStage(e)); @@ -55,7 +56,7 @@ class CgiResult : public TransformChainLink { const std::string encoding; }; -class WriteToCgiResult : public TransformImpl<WritableContent, CgiResult> { +class WritableToCgiResult : public TransformImpl<WritableContent, CgiResult> { public: void transform(const WritableContent * wc, CgiResult * cr) const { cr->header->addHeader("Content-Type", Glib::ustring::compose("%1; charset=%2", wc->getContentType(), cr->encoding)); @@ -63,23 +64,32 @@ class WriteToCgiResult : public TransformImpl<WritableContent, CgiResult> { wc->writeTo(cr->stream, cr->encoding); } }; -DECLARE_TRANSFORM(WriteToCgiResult); +DECLARE_TRANSFORM(WritableToCgiResult); -bool -addFinalTransformTarget(TransformSourcePtr ts, TransformChainLink * tcl) +class StaticToCgiResult : public TransformImpl<StaticContent, CgiResult> { + public: + void transform(const StaticContent * sc, CgiResult * cr) const { + cr->header->addHeader("Content-Type", Glib::ustring::compose("%1; charset=%2", sc->getContentType(), sc->getEncoding())); + cr->header->render(cr->stream); + sc->writeTo(cr->stream); + } +}; +DECLARE_TRANSFORM(StaticToCgiResult); + +TransformSourcePtr +finalTransformSource(TransformSourcePtr ts) { if (ts->getTargets().empty()) { - ts->addTarget(tcl, NULL); - return true; + return ts; } BOOST_FOREACH(const Targets::value_type & t, ts->getTargets()) { if (TransformSource * tr = dynamic_cast<TransformSource *>(t.first.get())) { - if (addFinalTransformTarget(tr, tcl)) { - return true; + if (TransformSourcePtr f = finalTransformSource(tr)) { + return f; } } } - return false; + return NULL; } void @@ -117,6 +127,7 @@ CgiApplicationEngine::process() const } while (currentStage.get<0>()); endTime = boost::date_time::microsec_clock<boost::posix_time::ptime>::universal_time(); ResponseStagePtr rs = currentStage.get<1>(); + outputCachingActive = !rs->caches.empty(); if (const MultiRowSetPresenter * p = currentStage.get<3>().get()) { addAppData(p, rs->outputOptions); addEnvData(p, rs->outputOptions); @@ -128,8 +139,12 @@ CgiApplicationEngine::process() const _env->getServerName().substr(_env->getServerName().find(".")), env()->sessionTimeOut, "/", false)); } if (TransformSourcePtr ts = currentStage.get<2>()) { - addFinalTransformTarget(ts, new CgiResult(header, IO, - rs && rs->root ? rs->root->value("encoding", _env->outputEncoding) : VariableType(_env->outputEncoding))); + TransformSourcePtr final = finalTransformSource(ts); + final->addTarget(new CgiResult(header, IO, + rs && rs->root ? rs->root->value("encoding", _env->outputEncoding) : VariableType(_env->outputEncoding)), NULL); + BOOST_FOREACH(const PresenterCachePtr & p, rs->caches) { + final->addTarget(p, NULL); + } std::fstream * ddd = NULL; if (!_env->dumpdatadoc.empty()) { ddd = new std::fstream(_env->dumpdatadoc.c_str(), std::fstream::trunc | std::fstream::out); @@ -169,8 +184,10 @@ CgiApplicationEngine::addEnvData(const MultiRowSetPresenter * p, OutputOptionsPt addEnvToPresenter(p, "serverport", &cgicc::CgiEnvironment::getServerPort); addEnvToPresenter(p, "serverhttps", &cgicc::CgiEnvironment::usingHTTPS); // Request stuff - addEnvToPresenter(p, "referrer", &cgicc::CgiEnvironment::getReferrer); - addEnvToPresenter(p, "querystring", &cgicc::CgiEnvironment::getQueryString); + if (!outputCachingActive) { + addEnvToPresenter(p, "referrer", &cgicc::CgiEnvironment::getReferrer); + addEnvToPresenter(p, "querystring", &cgicc::CgiEnvironment::getQueryString); + } p->finishRowSet(); } @@ -186,7 +203,7 @@ CgiApplicationEngine::addEnvData(const MultiRowSetPresenter * p, OutputOptionsPt p->finishRowSet(); } - if (!o || o->Parameters()) { + if (!outputCachingActive && (!o || o->Parameters())) { // Parameters p->addNewRowSet("params", env()->scriptNamespacePrefix); BOOST_FOREACH(cgicc::FormEntry fe, _env->cgi->getElements()) { @@ -214,7 +231,7 @@ CgiApplicationEngine::addAppData(const MultiRowSetPresenter * p, OutputOptionsPt if (!o || o->Core()) { addCoreAppData(p); } - if (!o || o->Session()) { + if (!outputCachingActive && (!o || o->Session())) { // Sessions variables p->addNewRowSet("session", env()->scriptNamespacePrefix); p->addAttribute("id", cursession->ID.str()); @@ -222,7 +239,7 @@ CgiApplicationEngine::addAppData(const MultiRowSetPresenter * p, OutputOptionsPt p->finishRowSet(); } - if (!o || o->Timing()) { + if (!outputCachingActive && (!o || o->Timing())) { // Timing info p->addNewRowSet("timing", env()->scriptNamespacePrefix); p->addAttribute("start", startTime); diff --git a/project2/cgi/cgiAppEngine.h b/project2/cgi/cgiAppEngine.h index 64f081d..b362ece 100644 --- a/project2/cgi/cgiAppEngine.h +++ b/project2/cgi/cgiAppEngine.h @@ -9,6 +9,7 @@ #include "viewHost.h" #include "transform.h" #include "xmlPresenter.h" +#include "presenterCache.h" #include "sessionContainer.h" #include <boost/intrusive_ptr.hpp> #include <boost/tuple/tuple.hpp> @@ -67,11 +68,14 @@ class CgiApplicationEngine : public ApplicationEngine, public TransformChainLink /// Base class for a stage that can be a response to the client class ResponseStage : public Stage { public: + typedef ANONORDEREDSTORAGEOF(PresenterCache) PresenterCaches; + ResponseStage(const CgiEnvironment * e, ScriptNodePtr root); virtual HttpHeaderPtr getHeader() const = 0; OutputOptionsPtr outputOptions; ScriptNodePtr root; + PresenterCaches caches; }; /// Stage implementation used to bootstrap the iteration process based on the CGI environment @@ -104,6 +108,17 @@ class CgiApplicationEngine : public ApplicationEngine, public TransformChainLink mutable MultiRowSetPresenterPtr presenter; }; + /// Stage to return previous cached output + class CacheHitStage : public virtual ResponseStage { + public: + CacheHitStage(const CgiEnvironment * e, ScriptNodePtr, PresenterCachePtr); + + virtual NextStage run(); + virtual HttpHeaderPtr getHeader() const; + protected: + PresenterCachePtr pc; + }; + /// The built-in fail-safe not found stage class DefaultNotFoundStage : public virtual ResponseStage { public: @@ -150,6 +165,7 @@ class CgiApplicationEngine : public ApplicationEngine, public TransformChainLink mutable NextStage currentStage; SessionPtr cursession; mutable std::ostream & IO; + mutable bool outputCachingActive; }; #endif diff --git a/project2/cgi/cgiEnvironment.cpp b/project2/cgi/cgiEnvironment.cpp index b1565ad..001d4bd 100644 --- a/project2/cgi/cgiEnvironment.cpp +++ b/project2/cgi/cgiEnvironment.cpp @@ -85,6 +85,12 @@ CgiEnvironment::getParamUri(unsigned int p) const return elems[p]; } +unsigned int +CgiEnvironment::getParamUriCount() const +{ + return elems.size(); +} + Glib::ustring CgiEnvironment::getParamQuery(const std::string & p) const { diff --git a/project2/cgi/cgiEnvironment.h b/project2/cgi/cgiEnvironment.h index 25ea90f..78f8730 100644 --- a/project2/cgi/cgiEnvironment.h +++ b/project2/cgi/cgiEnvironment.h @@ -28,6 +28,7 @@ class CgiEnvironment : public Environment, public cgicc::CgiEnvironment { virtual ~CgiEnvironment(); Glib::ustring getParamUri(unsigned int idx) const; + unsigned int getParamUriCount() const; Glib::ustring getParamQuery(const std::string & idx) const; std::string getServerName() const { return cgicc::CgiEnvironment::getServerName(); } std::string getScriptName() const { return cgicc::CgiEnvironment::getScriptName(); } diff --git a/project2/cgi/cgiStageCacheHit.cpp b/project2/cgi/cgiStageCacheHit.cpp new file mode 100644 index 0000000..728cc56 --- /dev/null +++ b/project2/cgi/cgiStageCacheHit.cpp @@ -0,0 +1,27 @@ +#include <pch.hpp> +#include "cgiAppEngine.h" +#include "cgiEnvironment.h" +#include "cgiHttpHeader.h" +#include <boost/foreach.hpp> +#include <boost/bind.hpp> + +CgiApplicationEngine::CacheHitStage::CacheHitStage(const CgiEnvironment * e, ScriptNodePtr s, PresenterCachePtr pcp) : + CgiApplicationEngine::ResponseStage(e, s), + pc(pcp) +{ +} + +CgiApplicationEngine::NextStage +CgiApplicationEngine::CacheHitStage::run() +{ + return NextStage(NULL, this, pc, NULL); +} + +CgiApplicationEngine::HttpHeaderPtr +CgiApplicationEngine::CacheHitStage::getHeader() const +{ + Project2HttpHeader * header = new Project2HttpHeader("200 OK"); + header->addHeader("Cache-control", "no-cache"); + return HttpHeaderPtr(header); +} + diff --git a/project2/cgi/cgiStagePresent.cpp b/project2/cgi/cgiStagePresent.cpp index 152b906..b5e73b5 100644 --- a/project2/cgi/cgiStagePresent.cpp +++ b/project2/cgi/cgiStagePresent.cpp @@ -13,12 +13,24 @@ CgiApplicationEngine::PresentStage::PresentStage(const CgiEnvironment * e, Scrip { s->loader.addLoadTarget(s->root(), Storer::into<OutputOptionsLoader>(&outputOptions)); s->loader.addLoadTarget(s->root(), Storer::into<PresenterLoader>(&presenter)); + s->loader.addLoadTarget(s->root(), Storer::into<ElementLoader>(&caches)); } CgiApplicationEngine::NextStage CgiApplicationEngine::PresentStage::run() { runChecks(); + PresenterCaches backFill; + BOOST_FOREACH(const PresenterCachePtr & pc, caches) { + if (pc->check()) { + CacheHitStage * chs = new CacheHitStage(e, root, pc); + chs->caches = backFill; + return NextStage(NULL, chs, pc, NULL); + } + else { + backFill.push_back(pc); + } + } try { executeViews(); return NextStage(NULL, this, boost::dynamic_pointer_cast<TransformSource>(presenter), presenter); |