aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mod/mod-build-force.cxx2
-rw-r--r--mod/mod-build-result.cxx4
-rw-r--r--mod/mod-build-task.cxx11
-rw-r--r--mod/mod-ci.cxx16
-rw-r--r--mod/mod-ci.hxx11
-rw-r--r--mod/module.cxx57
-rw-r--r--mod/module.hxx2
-rw-r--r--mod/tenant-service.hxx39
8 files changed, 110 insertions, 32 deletions
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<build> 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<build> 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<optional<string> (const brep::tenant_service&)> brep::ci::
build_queued (const tenant_service&,
const vector<build>& bs,
- optional<build_state> initial_state) const
+ optional<build_state> 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<string> r (ts.data);
@@ -424,7 +430,9 @@ build_queued (const tenant_service&,
}
function<optional<string> (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<optional<string> (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<optional<string> (const tenant_service&)>
build_queued (const tenant_service&,
const vector<build>&,
- optional<build_state> initial_state) const override;
+ optional<build_state> initial_state,
+ const diag_epilogue& log_writer) const noexcept override;
virtual function<optional<string> (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<optional<string> (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<butl::optional<std::string> (int)> (*) (std::function<butl::optional<std::string> (long)>);
+ // X brep::search::func (std::function<butl::optional<std::string> (char)> (*) (std::function<butl::optional<std::string> (wchar_t)>));
+ //
+ // std::function<std::optional<std::__cxx11::basic_string<char> >(int)> (* brep::search::func(std::function<std::optional<std::__cxx11::basic_string<char> >(char)> (*)(std::function<std::optional<std::__cxx11::basic_string<char> >(wchar_t)>)))(std::function<std::optional<std::__cxx11::basic_string<char> >(long int)>)
+ //
+ // 5) using X = std::function<butl::optional<std::string> (int)> (*) (std::function<butl::optional<std::string> (long)>);
+ // using Y = X (*) (int);
+ // Y brep::search::func (const char*);
+ //
+ // std::function<std::optional<std::__cxx11::basic_string<char> >(int)> (* (* brep::search::func(const char*))(int))(std::function<std::optional<std::__cxx11::basic_string<char> >(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 <libbrep/build.hxx>
+#include <mod/diagnostics.hxx>
+
namespace brep
{
class tenant_service_base
@@ -82,26 +84,57 @@ namespace brep
virtual function<optional<string> (const tenant_service&)>
build_queued (const tenant_service&,
const vector<build>&,
- optional<build_state> initial_state) const = 0;
+ optional<build_state> initial_state,
+ const diag_epilogue& log_writer) const noexcept = 0;
};
class tenant_service_build_building: public virtual tenant_service_base
{
public:
virtual function<optional<string> (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<optional<string> (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<string, shared_ptr<tenant_service_base>>;
+
+ // 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