From a7e49dbeab6c1a0500ca8fa3a1a6261b3740b6b0 Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Fri, 22 Mar 2024 16:04:51 +0300 Subject: Add NOTIFICATION_DIAG macro to mod/tenant-service.hxx --- mod/mod-build-force.cxx | 2 +- mod/mod-build-result.cxx | 4 ++-- mod/mod-build-task.cxx | 11 ++++++---- mod/mod-ci.cxx | 16 +++++++++++--- mod/mod-ci.hxx | 11 +++++++--- mod/module.cxx | 57 +++++++++++++++++++++++++++++++++++------------- mod/module.hxx | 2 +- mod/tenant-service.hxx | 39 ++++++++++++++++++++++++++++++--- 8 files changed, 110 insertions(+), 32 deletions(-) (limited to 'mod') diff --git a/mod/mod-build-force.cxx b/mod/mod-build-force.cxx index dea89de..2eddb10 100644 --- a/mod/mod-build-force.cxx +++ b/mod/mod-build-force.cxx @@ -280,7 +280,7 @@ handle (request& rq, response& rs) vector qbs; qbs.push_back (move (b)); - if (auto f = tsq->build_queued (ss, qbs, build_state::building)) + if (auto f = tsq->build_queued (ss, qbs, build_state::building, log_writer_)) update_tenant_service_state (conn, qbs.back ().tenant, f); } diff --git a/mod/mod-build-result.cxx b/mod/mod-build-result.cxx index 77018d9..605f83d 100644 --- a/mod/mod-build-result.cxx +++ b/mod/mod-build-result.cxx @@ -503,7 +503,7 @@ handle (request& rq, response&) vector qbs; qbs.push_back (move (*tss->second)); - if (auto f = tsq->build_queued (ss, qbs, build_state::building)) + if (auto f = tsq->build_queued (ss, qbs, build_state::building, log_writer_)) update_tenant_service_state (conn, qbs.back ().tenant, f); } @@ -518,7 +518,7 @@ handle (request& rq, response&) const tenant_service& ss (tss->first); const build& b (*tss->second); - if (auto f = tsb->build_built (ss, b)) + if (auto f = tsb->build_built (ss, b, log_writer_)) update_tenant_service_state (conn, b.tenant, f); } diff --git a/mod/mod-build-task.cxx b/mod/mod-build-task.cxx index 29f3783..0892638 100644 --- a/mod/mod-build-task.cxx +++ b/mod/mod-build-task.cxx @@ -2060,7 +2060,10 @@ handle (request& rq, response& rs) if (!qbs.empty ()) { - if (auto f = tsq->build_queued (ss, qbs, nullopt /* initial_state */)) + if (auto f = tsq->build_queued (ss, + qbs, + nullopt /* initial_state */, + log_writer_)) update_tenant_service_state (conn, qbs.back ().tenant, f); } @@ -2076,7 +2079,7 @@ handle (request& rq, response& rs) qbs.push_back (move (b)); restore_build = true; - if (auto f = tsq->build_queued (ss, qbs, initial_state)) + if (auto f = tsq->build_queued (ss, qbs, initial_state, log_writer_)) update_tenant_service_state (conn, qbs.back ().tenant, f); } @@ -2096,7 +2099,7 @@ handle (request& rq, response& rs) const tenant_service& ss (tss->first); const build& b (*tss->second); - if (auto f = tsb->build_building (ss, b)) + if (auto f = tsb->build_building (ss, b, log_writer_)) update_tenant_service_state (conn, b.tenant, f); } @@ -2209,7 +2212,7 @@ handle (request& rq, response& rs) const tenant_service& ss (tss->first); const build& b (*tss->second); - if (auto f = tsb->build_built (ss, b)) + if (auto f = tsb->build_built (ss, b, log_writer_)) update_tenant_service_state (conn, b.tenant, f); } } diff --git a/mod/mod-ci.cxx b/mod/mod-ci.cxx index fec603e..94a6882 100644 --- a/mod/mod-ci.cxx +++ b/mod/mod-ci.cxx @@ -391,8 +391,14 @@ handle (request& rq, response& rs) function (const brep::tenant_service&)> brep::ci:: build_queued (const tenant_service&, const vector& bs, - optional initial_state) const + optional initial_state, + const diag_epilogue& log_writer) const noexcept { + NOTIFICATION_DIAG (log_writer); + + l2 ([&]{trace << "initial_state: " + << (initial_state ? to_string (*initial_state) : "none");}); + return [&bs, initial_state] (const tenant_service& ts) { optional r (ts.data); @@ -424,7 +430,9 @@ build_queued (const tenant_service&, } function (const brep::tenant_service&)> brep::ci:: -build_building (const tenant_service&, const build& b) const +build_building (const tenant_service&, + const build& b, + const diag_epilogue&) const noexcept { return [&b] (const tenant_service& ts) { @@ -442,7 +450,9 @@ build_building (const tenant_service&, const build& b) const } function (const brep::tenant_service&)> brep::ci:: -build_built (const tenant_service&, const build& b) const +build_built (const tenant_service&, + const build& b, + const diag_epilogue&) const noexcept { return [&b] (const tenant_service& ts) { diff --git a/mod/mod-ci.hxx b/mod/mod-ci.hxx index dc109c2..48d42ee 100644 --- a/mod/mod-ci.hxx +++ b/mod/mod-ci.hxx @@ -61,13 +61,18 @@ namespace brep virtual function (const tenant_service&)> build_queued (const tenant_service&, const vector&, - optional initial_state) const override; + optional initial_state, + const diag_epilogue& log_writer) const noexcept override; virtual function (const tenant_service&)> - build_building (const tenant_service&, const build&) const override; + build_building (const tenant_service&, + const build&, + const diag_epilogue& log_writer) const noexcept override; virtual function (const tenant_service&)> - build_built (const tenant_service&, const build&) const override; + build_built (const tenant_service&, + const build&, + const diag_epilogue& log_writer) const noexcept override; #endif private: diff --git a/mod/module.cxx b/mod/module.cxx index 2fcadd2..c8d0595 100644 --- a/mod/module.cxx +++ b/mod/module.cxx @@ -241,23 +241,46 @@ namespace brep initialized_ = m.initialized_; } -// For function func declared like this: -// using B = std::string (*)(int); -// using A = B (*)(int,int); -// A func(B (*)(char),B (*)(wchar_t)); -// __PRETTY_FUNCTION__ looks like this: -// virtual std::string (* (* brep::search::func(std::string (* (*)(char))(int) -// ,std::string (* (*)(wchar_t))(int)) const)(int, int))(int) -// + // Here are examples of __PRETTY_FUNCTION__ for some function declarations: + // + // 1) virtual bool brep::search::handle (web::request&, web::response&); + // + // virtual bool brep::search::handle(web::request&, web::response&) + // + // 2) using B = std::string (*) (int); + // virtual B brep::search::func (); + // + // virtual std::string (* brep::search::func())(int) + // + // 3) using B = std::string (*) (int); + // using A = B (*) (int,int); + // virtual A brep::search::func (B (*) (char), B (*) (wchar_t)); + // + // virtual std::string (* (* brep::search::func(std::string (* (*)(char))(int), std::string (* (*)(wchar_t))(int)))(int, int))(int) + // + // 4) using X = std::function (int)> (*) (std::function (long)>); + // X brep::search::func (std::function (char)> (*) (std::function (wchar_t)>)); + // + // std::function >(int)> (* brep::search::func(std::function >(char)> (*)(std::function >(wchar_t)>)))(std::function >(long int)>) + // + // 5) using X = std::function (int)> (*) (std::function (long)>); + // using Y = X (*) (int); + // Y brep::search::func (const char*); + // + // std::function >(int)> (* (* brep::search::func(const char*))(int))(std::function >(long int)>) + // string handler:: func_name (const char* pretty_name) { - const char* e (strchr (pretty_name, ')')); + // Position at the last ')' character, which is either the end of the + // function's arguments list or the returned function type argument list. + // + const char* e (strrchr (pretty_name, ')')); if (e && e > pretty_name) { - // Position e at last matching '(' which is the beginning of the - // argument list.. + // Position e at the matching '(' character which is the beginning of + // the mentioned argument list. // size_t d (1); @@ -273,11 +296,15 @@ namespace brep if (!d && e > pretty_name) { - // Position e at the character following the function name. + // Position e at the character which follows the function name. + // + // Specifically, go further to the left and stop at the '(' character + // which is preceded by the character other than ' ', ')', of '>'. // - while (e > pretty_name && - (*e != '(' || *(e - 1) == ' ' || *(e - 1) == ')')) - --e; + for (char c; + e > pretty_name && + !(*e == '(' && (c = *(e - 1)) != ' ' && c != ')' && c != '>'); + --e) ; if (e > pretty_name) { diff --git a/mod/module.hxx b/mod/module.hxx index 6423e6d..f3e062e 100644 --- a/mod/module.hxx +++ b/mod/module.hxx @@ -194,7 +194,7 @@ namespace brep log* log_ {nullptr}; // Diagnostics backend provided by the web server. private: - // Extract function name from a __PRETTY_FUNCTION__. + // Extract the full-qualified function name from a __PRETTY_FUNCTION__. // Throw invalid_argument if fail to parse. // static string diff --git a/mod/tenant-service.hxx b/mod/tenant-service.hxx index a7bc941..46f2822 100644 --- a/mod/tenant-service.hxx +++ b/mod/tenant-service.hxx @@ -11,6 +11,8 @@ #include +#include + namespace brep { class tenant_service_base @@ -82,26 +84,57 @@ namespace brep virtual function (const tenant_service&)> build_queued (const tenant_service&, const vector&, - optional initial_state) const = 0; + optional initial_state, + const diag_epilogue& log_writer) const noexcept = 0; }; class tenant_service_build_building: public virtual tenant_service_base { public: virtual function (const tenant_service&)> - build_building (const tenant_service&, const build&) const = 0; + build_building (const tenant_service&, + const build&, + const diag_epilogue& log_writer) const noexcept = 0; }; class tenant_service_build_built: public virtual tenant_service_base { public: virtual function (const tenant_service&)> - build_built (const tenant_service&, const build&) const = 0; + build_built (const tenant_service&, + const build&, + const diag_epilogue& log_writer) const noexcept = 0; }; // Map of service type (tenant_service::type) to service. // using tenant_service_map = std::map>; + + // Every notification callback function that needs to produce any + // diagnostics shall begin with: + // + // NOTIFICATION_DIAG (log_writer); + // + // This will instantiate the error, warn, info, and trace diagnostics + // streams with the function's name. + // + // Note that a callback function is not expected to throw any exceptions. + // This is, in particular, why this macro doesn't instantiate the fail + // diagnostics stream. + // +#define NOTIFICATION_DIAG(log_writer) \ + const basic_mark error (severity::error, \ + log_writer, \ + __PRETTY_FUNCTION__); \ + const basic_mark warn (severity::warning, \ + log_writer, \ + __PRETTY_FUNCTION__); \ + const basic_mark info (severity::info, \ + log_writer, \ + __PRETTY_FUNCTION__); \ + const basic_mark trace (severity::trace, \ + log_writer, \ + __PRETTY_FUNCTION__) } #endif // MOD_TENANT_SERVICE_HXX -- cgit v1.1