From b45b34edb132d59c44f0c75e3baba40be2b49757 Mon Sep 17 00:00:00 2001 From: ethanlabelle <37966268+ethanlabelle@users.noreply.github.com> Date: Tue, 14 Jun 2022 14:50:42 -0400 Subject: [PATCH] append warning to response if clio is out of date (#175) Fixes #46. --- src/etl/ReportingETL.h | 33 +++++++++++++++++++-------------- src/webserver/HttpBase.h | 20 ++++++++++++++++++-- src/webserver/WsBase.h | 23 ++++++++++++++++++++++- 3 files changed, 59 insertions(+), 17 deletions(-) diff --git a/src/etl/ReportingETL.h b/src/etl/ReportingETL.h index 9ab108f70..3c68d35d0 100644 --- a/src/etl/ReportingETL.h +++ b/src/etl/ReportingETL.h @@ -130,19 +130,12 @@ private: /// server_info std::chrono::time_point lastPublish_; - mutable std::mutex publishTimeMtx_; - - std::chrono::time_point - getLastPublish() const - { - std::unique_lock lck(publishTimeMtx_); - return lastPublish_; - } + mutable std::shared_mutex publishTimeMtx_; void setLastPublish() { - std::unique_lock lck(publishTimeMtx_); + std::unique_lock lck(publishTimeMtx_); lastPublish_ = std::chrono::system_clock::now(); } @@ -322,13 +315,25 @@ public: result["read_only"] = readOnly_; auto last = getLastPublish(); if (last.time_since_epoch().count() != 0) - result["last_publish_age_seconds"] = std::to_string( - std::chrono::duration_cast( - std::chrono::system_clock::now() - getLastPublish()) - .count()); - + result["last_publish_age_seconds"] = + std::to_string(lastPublishAgeSeconds()); return result; } + + std::chrono::time_point + getLastPublish() const + { + std::shared_lock lck(publishTimeMtx_); + return lastPublish_; + } + + std::uint32_t + lastPublishAgeSeconds() const + { + return std::chrono::duration_cast( + std::chrono::system_clock::now() - getLastPublish()) + .count(); + } }; #endif diff --git a/src/webserver/HttpBase.h b/src/webserver/HttpBase.h index da05563c5..0b16f12b5 100644 --- a/src/webserver/HttpBase.h +++ b/src/webserver/HttpBase.h @@ -405,9 +405,25 @@ handle_request( responseStr = boost::json::serialize(response); } + auto warningFlag = false; + boost::json::array warnings; if (!dosGuard.add(ip, responseStr.size())) - result["warning"] = "Too many requests"; - + { + warnings.emplace_back("Too many requests"); + warningFlag = true; + } + auto lastPublishAge = context->etl->lastPublishAgeSeconds(); + if (lastPublishAge >= 60) + { + warnings.emplace_back("This server may be out of date"); + warningFlag = true; + } + // reserialize only if a warning was appended. + if (warningFlag) + { + result["warning"] = warnings; + responseStr = boost::json::serialize(response); + } return send( httpResponse(http::status::ok, "application/json", responseStr)); } diff --git a/src/webserver/WsBase.h b/src/webserver/WsBase.h index 9a6bbc6ac..2d4d313fd 100644 --- a/src/webserver/WsBase.h +++ b/src/webserver/WsBase.h @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -322,7 +323,27 @@ public: } std::string responseStr = boost::json::serialize(response); - dosGuard_.add(*ip, responseStr.size()); + boost::json::array warnings; + auto warningFlag = false; + + if (!dosGuard_.add(*ip, responseStr.size())) + { + warnings.emplace_back("Too many requests"); + warningFlag = true; + } + auto lastPublishAge = etl_->lastPublishAgeSeconds(); + if (lastPublishAge >= 60) + { + warnings.emplace_back("This server may be out of date"); + warningFlag = true; + } + // reserialize if a warning was appended + if (warningFlag) + { + auto& result = response["result"].as_object(); + result["warning"] = warnings; + responseStr = boost::json::serialize(response); + } send(std::move(responseStr)); }