There are somecases I have to add statement, like logs or trace to an expression, for example (I wanna log exactly the time for prep_stmt.executeQuery()
and still I need its return value):
zdb::PreparedStatement prep_stmt = conn.prepareStatement(sql.data());
prep_stmt.setLLong(1, key);
zdb::ResultSet result = prep_stmt.executeQuery();
// do some stuff with the result
if (result.next()) {
SCOPE_LOG(HANDLE_RESULTS);
auto [data, size] = result.getBlob("v");
// value is a protobuff message
value->ParseFromArray(image, size);
}
Say I wanna log the time ellasped in prep_stmt.executeQuery()
. So I add some macros like these:
// only for debug
#define EXPR_LOG_BEGIN(Name) \
[&]() { \
SCOPE_LOG(Name); \
return
#define EXPR_LOG_END }();
here SCOPE_LOG
is a macro for logging using raii (folly's SCOPE_EXIT macro and spdlog):
#define SCOPE_LOG(Expr) \
auto start = chrono::system_clock::now(); \
SCOPE_EXIT { \
auto end = std::chrono::system_clock::now(); \
std::chrono::duration<double, std::milli> elapsed_milliseconds = end - start; \
SPDLOG_LOGGER_INFO(::Logger::getLogger(), \
"[[title={},elapsed_ms={}]]", \
#Expr, elapsed_milliseconds.count()); \
}
And change the above code to:
zdb::PreparedStatement prep_stmt = conn.prepareStatement(sql.data());
prep_stmt.setLLong(1, key);
zdb::ResultSet result =
EXPR_LOG_BEGIN(DB_Execute)
prep_stmt.executeQuery();
EXPR_LOG_END
So the code is expanded to:
zdb::PreparedStatement prep_stmt = conn.prepareStatement(sql.data());
prep_stmt.setLLong(1, key);
zdb::ResultSet result = [&]() {
SCOPE_LOG(Name);
return prep_stmt.executeQuery();
}();
Is it safe to du this stuff? will it be any hidden bug for using an immediate lambda for adding statement for an expression? Is there any better way to do this? I found a similar question: How to immediately invoke a C++ lambda? but it does not state its usecases explicitly
Aucun commentaire:
Enregistrer un commentaire