diff --git a/examples/base/lifetime_tag/Makefile b/examples/base/lifetime_tag/Makefile new file mode 100644 index 00000000..ab83cec2 --- /dev/null +++ b/examples/base/lifetime_tag/Makefile @@ -0,0 +1,29 @@ +# +# .============. +# // M A K E / \ +# // C++ DEV / \ +# // E A S Y / \/ \ +# ++ ----------. \/\ . +# \\ \ \ /\ / +# \\ \ \ / +# \\ \ \ / +# -============' +# +# Copyright (c) 2018 Hevake and contributors, all rights reserved. +# +# This file is part of cpp-tbox (https://github.com/cpp-main/cpp-tbox) +# Use of this source code is governed by MIT license that can be found +# in the LICENSE file in the root of the source tree. All contributing +# project authors may be found in the CONTRIBUTORS.md file in the root +# of the source tree. +# + +PROJECT := examples/base/lifetime_tag +EXE_NAME := ${PROJECT} + +CPP_SRC_FILES := main.cpp + +CXXFLAGS := -DMODULE_ID='"$(EXE_NAME)"' $(CXXFLAGS) +LDFLAGS += -ltbox_base -ldl + +include $(TOP_DIR)/mk/exe_common.mk diff --git a/examples/base/lifetime_tag/main.cpp b/examples/base/lifetime_tag/main.cpp new file mode 100644 index 00000000..7d76eda8 --- /dev/null +++ b/examples/base/lifetime_tag/main.cpp @@ -0,0 +1,47 @@ +/* + * .============. + * // M A K E / \ + * // C++ DEV / \ + * // E A S Y / \/ \ + * ++ ----------. \/\ . + * \\ \ \ /\ / + * \\ \ \ / + * \\ \ \ / + * -============' + * + * Copyright (c) 2026 Hevake and contributors, all rights reserved. + * + * This file is part of cpp-tbox (https://github.com/cpp-main/cpp-tbox) + * Use of this source code is governed by MIT license that can be found + * in the LICENSE file in the root of the source tree. All contributing + * project authors may be found in the CONTRIBUTORS.md file in the root + * of the source tree. + */ +#include +#include + +using namespace std; + +int main() +{ + struct Tmp { + int value; + tbox::LifetimeTag lifetime_tag; + }; + + auto tmp = new Tmp{10}; + auto watch = tmp->lifetime_tag.get(); + auto print_func = [tmp, watch] (const char *prompt) { + if (watch) + cout << '[' << prompt << "] it's alive, value " << tmp->value << endl; + else + cout << '[' << prompt << "] it's not alive" << endl; + }; + + print_func("A"); //! it's alive, value 10 + delete tmp; + + print_func("B"); //! it's not alive + + return 0; +} diff --git a/examples/main/07_stop_process/Makefile b/examples/main/07_stop_process/Makefile new file mode 100644 index 00000000..e3753a10 --- /dev/null +++ b/examples/main/07_stop_process/Makefile @@ -0,0 +1,43 @@ +# +# .============. +# // M A K E / \ +# // C++ DEV / \ +# // E A S Y / \/ \ +# ++ ----------. \/\ . +# \\ \ \ /\ / +# \\ \ \ / +# \\ \ \ / +# -============' +# +# Copyright (c) 2018 Hevake and contributors, all rights reserved. +# +# This file is part of cpp-tbox (https://github.com/cpp-main/cpp-tbox) +# Use of this source code is governed by MIT license that can be found +# in the LICENSE file in the root of the source tree. All contributing +# project authors may be found in the CONTRIBUTORS.md file in the root +# of the source tree. +# + +PROJECT := examples/main/07_stop_process +EXE_NAME := ${PROJECT} + +CPP_SRC_FILES = app.cpp main.cpp + +CXXFLAGS := -DMODULE_ID='"$(EXE_NAME)"' $(CXXFLAGS) +LDFLAGS += \ + -ltbox_main \ + -ltbox_coroutine \ + -ltbox_trace \ + -ltbox_terminal \ + -ltbox_network \ + -ltbox_eventx \ + -ltbox_eventx \ + -ltbox_event \ + -ltbox_log \ + -ltbox_util \ + -ltbox_base \ + -lpthread \ + -ldl \ + -rdynamic + +include $(TOP_DIR)/mk/exe_common.mk diff --git a/examples/main/07_stop_process/app.cpp b/examples/main/07_stop_process/app.cpp new file mode 100644 index 00000000..a05442b3 --- /dev/null +++ b/examples/main/07_stop_process/app.cpp @@ -0,0 +1,37 @@ +/* + * .============. + * // M A K E / \ + * // C++ DEV / \ + * // E A S Y / \/ \ + * ++ ----------. \/\ . + * \\ \ \ /\ / + * \\ \ \ / + * \\ \ \ / + * -============' + * + * Copyright (c) 2018 Hevake and contributors, all rights reserved. + * + * This file is part of cpp-tbox (https://github.com/cpp-main/cpp-tbox) + * Use of this source code is governed by MIT license that can be found + * in the LICENSE file in the root of the source tree. All contributing + * project authors may be found in the CONTRIBUTORS.md file in the root + * of the source tree. + */ +#include "app.h" +#include +#include + +App::App(tbox::main::Context &ctx) : + Module("app", ctx) +{ } + +bool App::onStart() +{ + LogInfo("process will exit after 5 sec"); + ctx().timer_pool()->doAfter(std::chrono::seconds(5), + [this] { + tbox::main::RaiseStopSignal(); + } + ); + return true; +} diff --git a/examples/main/07_stop_process/app.h b/examples/main/07_stop_process/app.h new file mode 100644 index 00000000..0218c1ab --- /dev/null +++ b/examples/main/07_stop_process/app.h @@ -0,0 +1,34 @@ +/* + * .============. + * // M A K E / \ + * // C++ DEV / \ + * // E A S Y / \/ \ + * ++ ----------. \/\ . + * \\ \ \ /\ / + * \\ \ \ / + * \\ \ \ / + * -============' + * + * Copyright (c) 2018 Hevake and contributors, all rights reserved. + * + * This file is part of cpp-tbox (https://github.com/cpp-main/cpp-tbox) + * Use of this source code is governed by MIT license that can be found + * in the LICENSE file in the root of the source tree. All contributing + * project authors may be found in the CONTRIBUTORS.md file in the root + * of the source tree. + */ +#ifndef TBOX_MAIN_EXAMPLE_SAMPLE_H_20211226 +#define TBOX_MAIN_EXAMPLE_SAMPLE_H_20211226 + +#include + +class App : public tbox::main::Module +{ + public: + App(tbox::main::Context &ctx); + + protected: + virtual bool onStart() override; +}; + +#endif //TBOX_MAIN_EXAMPLE_SAMPLE_H_20211226 diff --git a/examples/main/07_stop_process/main.cpp b/examples/main/07_stop_process/main.cpp new file mode 100644 index 00000000..91364e90 --- /dev/null +++ b/examples/main/07_stop_process/main.cpp @@ -0,0 +1,32 @@ +/* + * .============. + * // M A K E / \ + * // C++ DEV / \ + * // E A S Y / \/ \ + * ++ ----------. \/\ . + * \\ \ \ /\ / + * \\ \ \ / + * \\ \ \ / + * -============' + * + * Copyright (c) 2018 Hevake and contributors, all rights reserved. + * + * This file is part of cpp-tbox (https://github.com/cpp-main/cpp-tbox) + * Use of this source code is governed by MIT license that can be found + * in the LICENSE file in the root of the source tree. All contributing + * project authors may be found in the CONTRIBUTORS.md file in the root + * of the source tree. + */ +#include +#include "app.h" + +namespace tbox { +namespace main { + +void RegisterApps(Module &apps, Context &ctx) +{ + apps.add(new ::App(ctx)); +} + +} +} diff --git a/modules/base/backtrace_test.cpp b/modules/base/backtrace_test.cpp index c59f4889..76120c53 100644 --- a/modules/base/backtrace_test.cpp +++ b/modules/base/backtrace_test.cpp @@ -27,7 +27,7 @@ namespace tbox { TEST(Backtrace, _) { LogOutput_Enable(); - LogBacktrace(LOG_LEVEL_TRACE); + LogBacktrace(TBOX_LOG_LEVEL_TRACE); LogOutput_Disable(); } diff --git a/modules/base/catch_throw.cpp b/modules/base/catch_throw.cpp index 3212442a..43392136 100644 --- a/modules/base/catch_throw.cpp +++ b/modules/base/catch_throw.cpp @@ -51,7 +51,7 @@ void CatchType() } -bool CatchThrow(const std::function &func, +bool CatchThrow(const std::function &func, const char *tag, bool print_backtrace, bool abort_process) noexcept { try { @@ -61,22 +61,22 @@ bool CatchThrow(const std::function &func, } catch (const std::exception &e) { CatchType(); - LogWarn("what(): %s", e.what()); + LogWarn("'%s' what(): %s", tag, e.what()); } catch (const char *e) { CatchType(); - LogWarn("value: %s", e); + LogWarn("'%s' value: %s", tag, e); } catch (int e) { CatchType(); - LogWarn("value: %d", e); + LogWarn("'%s' value: %d", tag, e); } catch (double e) { CatchType(); - LogWarn("value: %f", e); + LogWarn("'%s' value: %f", tag, e); } catch (const std::string &e) { CatchType(); - LogWarn("value: %s", e.c_str()); + LogWarn("'%s' value: %s", tag, e.c_str()); } catch (...) { CatchType(); - LogWarn("can't print value"); + LogWarn("'%s' can't print value", tag); } if (print_backtrace) { diff --git a/modules/base/catch_throw.h b/modules/base/catch_throw.h index 35ff6a31..2baef384 100644 --- a/modules/base/catch_throw.h +++ b/modules/base/catch_throw.h @@ -34,6 +34,7 @@ namespace tbox { * \return true 运行过程中捕获到了异常 */ bool CatchThrow(const std::function &func, + const char *tag = "?", bool print_backtrace = false, bool abort_process = false) noexcept; diff --git a/modules/base/catch_throw_test.cpp b/modules/base/catch_throw_test.cpp index a0f88142..d2884e92 100644 --- a/modules/base/catch_throw_test.cpp +++ b/modules/base/catch_throw_test.cpp @@ -114,7 +114,7 @@ TEST(CatchThrow, ThrowPrintStack) bool has_catch = CatchThrow([&]{ throw 10; - }, true); + }, "ThrowPrintStack", true); EXPECT_TRUE(has_catch); diff --git a/modules/base/lifetime_tag.hpp b/modules/base/lifetime_tag.hpp index 14a82001..fbf4e98c 100644 --- a/modules/base/lifetime_tag.hpp +++ b/modules/base/lifetime_tag.hpp @@ -20,6 +20,8 @@ #ifndef TBOX_LIFETIME_TAG_H_20221215 #define TBOX_LIFETIME_TAG_H_20221215 +#include + namespace tbox { /** diff --git a/modules/base/log.h b/modules/base/log.h index 3e9b1063..248872fa 100644 --- a/modules/base/log.h +++ b/modules/base/log.h @@ -22,15 +22,15 @@ #define TBOX_LOG_H_20170512 //! Define log levels -#define LOG_LEVEL_FATAL 0 //!< Program will crash -#define LOG_LEVEL_ERROR 1 //!< Got serious problem, program can't handle -#define LOG_LEVEL_WARN 2 //!< Got inner abnormal situation, but program can handle it -#define LOG_LEVEL_NOTICE 3 //!< It not big problem, but we should notice it, such as invalid data input -#define LOG_LEVEL_IMPORTANT 4 //!< Important message -#define LOG_LEVEL_INFO 5 //!< Normal message exchange with other program -#define LOG_LEVEL_DEBUG 6 //!< Normal process inside program -#define LOG_LEVEL_TRACE 7 //!< Temporary debugging log -#define LOG_LEVEL_MAX 8 //!< MAX +#define TBOX_LOG_LEVEL_FATAL 0 //!< Program will crash +#define TBOX_LOG_LEVEL_ERROR 1 //!< Got serious problem, program can't handle +#define TBOX_LOG_LEVEL_WARN 2 //!< Got inner abnormal situation, but program can handle it +#define TBOX_LOG_LEVEL_NOTICE 3 //!< It not big problem, but we should notice it, such as invalid data input +#define TBOX_LOG_LEVEL_IMPORTANT 4 //!< Important message +#define TBOX_LOG_LEVEL_INFO 5 //!< Normal message exchange with other program +#define TBOX_LOG_LEVEL_DEBUG 6 //!< Normal process inside program +#define TBOX_LOG_LEVEL_TRACE 7 //!< Temporary debugging log +#define TBOX_LOG_LEVEL_MAX 8 //!< MAX //! Module ID #ifndef LOG_MODULE_ID @@ -49,28 +49,28 @@ #define LogPuts(level, text) \ LogPrintfFunc(LOG_MODULE_ID, __func__, __FILE__, __LINE__, level, 0, text) -#define LogFatal(fmt, ...) LogPrintf(LOG_LEVEL_FATAL, fmt, ## __VA_ARGS__) -#define LogErr(fmt, ...) LogPrintf(LOG_LEVEL_ERROR, fmt, ## __VA_ARGS__) -#define LogWarn(fmt, ...) LogPrintf(LOG_LEVEL_WARN, fmt, ## __VA_ARGS__) -#define LogNotice(fmt, ...) LogPrintf(LOG_LEVEL_NOTICE, fmt, ## __VA_ARGS__) -#define LogImportant(fmt, ...) LogPrintf(LOG_LEVEL_IMPORTANT, fmt, ## __VA_ARGS__) -#define LogInfo(fmt, ...) LogPrintf(LOG_LEVEL_INFO, fmt, ## __VA_ARGS__) +#define LogFatal(fmt, ...) LogPrintf(TBOX_LOG_LEVEL_FATAL, fmt, ## __VA_ARGS__) +#define LogErr(fmt, ...) LogPrintf(TBOX_LOG_LEVEL_ERROR, fmt, ## __VA_ARGS__) +#define LogWarn(fmt, ...) LogPrintf(TBOX_LOG_LEVEL_WARN, fmt, ## __VA_ARGS__) +#define LogNotice(fmt, ...) LogPrintf(TBOX_LOG_LEVEL_NOTICE, fmt, ## __VA_ARGS__) +#define LogImportant(fmt, ...) LogPrintf(TBOX_LOG_LEVEL_IMPORTANT, fmt, ## __VA_ARGS__) +#define LogInfo(fmt, ...) LogPrintf(TBOX_LOG_LEVEL_INFO, fmt, ## __VA_ARGS__) -#if !defined(STATIC_LOG_LEVEL) || (STATIC_LOG_LEVEL >= LOG_LEVEL_DEBUG) - #define LogDbg(fmt, ...) LogPrintf(LOG_LEVEL_DEBUG, fmt, ## __VA_ARGS__) +#if !defined(STATIC_LOG_LEVEL) || (STATIC_LOG_LEVEL >= TBOX_LOG_LEVEL_DEBUG) + #define LogDbg(fmt, ...) LogPrintf(TBOX_LOG_LEVEL_DEBUG, fmt, ## __VA_ARGS__) #else #define LogDbg(fmt, ...) #endif -#if !defined(STATIC_LOG_LEVEL) || (STATIC_LOG_LEVEL >= LOG_LEVEL_TRACE) - #define LogTrace(fmt, ...) LogPrintf(LOG_LEVEL_TRACE, fmt, ## __VA_ARGS__) - #define LogTag() LogPuts(LOG_LEVEL_TRACE, "==> Run Here <==") +#if !defined(STATIC_LOG_LEVEL) || (STATIC_LOG_LEVEL >= TBOX_LOG_LEVEL_TRACE) + #define LogTrace(fmt, ...) LogPrintf(TBOX_LOG_LEVEL_TRACE, fmt, ## __VA_ARGS__) + #define LogTag() LogPuts(TBOX_LOG_LEVEL_TRACE, "==> Run Here <==") #else #define LogTrace(fmt, ...) #define LogTag() #endif -#define LogUndo() LogPuts(LOG_LEVEL_NOTICE, "!!! Undo !!!") +#define LogUndo() LogPuts(TBOX_LOG_LEVEL_NOTICE, "!!! Undo !!!") //! 打印错误码,需要 #include #define LogErrno(err, fmt, ...) LogErr("Errno:%d(%s) " fmt, (err), strerror(err), ## __VA_ARGS__) diff --git a/modules/base/log_impl.cpp b/modules/base/log_impl.cpp index cd4682df..991518e2 100644 --- a/modules/base/log_impl.cpp +++ b/modules/base/log_impl.cpp @@ -72,11 +72,11 @@ void Dispatch(const LogContent &content) } -const char LOG_LEVEL_LEVEL_CODE[LOG_LEVEL_MAX] = { +const char TBOX_LOG_LEVEL_LEVEL_CODE[TBOX_LOG_LEVEL_MAX] = { 'F', 'E', 'W', 'N', 'I', 'I', 'D', 'T' }; -const char* LOG_LEVEL_COLOR_CODE[LOG_LEVEL_MAX] = { +const char* TBOX_LOG_LEVEL_COLOR_CODE[TBOX_LOG_LEVEL_MAX] = { "7;91", //! FATAL 文字黑,背景亮红 "31", //! ERROR 红 "7;93", //! WARN 文字黑,背景亮黄 @@ -116,7 +116,7 @@ void LogPrintfFunc(const char *module_id, const char *func_name, const char *fil return; if (level < 0) level = 0; - if (level >= LOG_LEVEL_MAX) level = (LOG_LEVEL_MAX - 1); + if (level >= TBOX_LOG_LEVEL_MAX) level = (TBOX_LOG_LEVEL_MAX - 1); const char *module_id_be_print = (module_id != nullptr) ? module_id : "???"; diff --git a/modules/base/log_impl.h b/modules/base/log_impl.h index 8955222c..b6a490d9 100644 --- a/modules/base/log_impl.h +++ b/modules/base/log_impl.h @@ -54,8 +54,8 @@ struct LogContent { }; //! 日志等级颜色表 -extern const char LOG_LEVEL_LEVEL_CODE[LOG_LEVEL_MAX]; -extern const char* LOG_LEVEL_COLOR_CODE[LOG_LEVEL_MAX]; +extern const char TBOX_LOG_LEVEL_LEVEL_CODE[TBOX_LOG_LEVEL_MAX]; +extern const char* TBOX_LOG_LEVEL_COLOR_CODE[TBOX_LOG_LEVEL_MAX]; //! 定义日志输出函数 typedef void (*LogPrintfFuncType)(const LogContent *content, void *ptr); diff --git a/modules/base/log_output.cpp b/modules/base/log_output.cpp index b557a644..b02e1601 100644 --- a/modules/base/log_output.cpp +++ b/modules/base/log_output.cpp @@ -57,7 +57,7 @@ namespace { //! 打印色彩、等级、时间戳、线程号、模块名 printf("\033[%sm%c %s %ld %s ", - LOG_LEVEL_COLOR_CODE[content->level], LOG_LEVEL_LEVEL_CODE[content->level], + TBOX_LOG_LEVEL_COLOR_CODE[content->level], TBOX_LOG_LEVEL_LEVEL_CODE[content->level], timestamp, content->thread_id, content->module_id); if (content->func_name != nullptr) diff --git a/modules/base/log_output_test.cpp b/modules/base/log_output_test.cpp index 73b98f11..7af761f4 100644 --- a/modules/base/log_output_test.cpp +++ b/modules/base/log_output_test.cpp @@ -49,7 +49,7 @@ TEST(Log, Format) TEST(Log, LogPuts) { LogOutput_Enable(); - LogPuts(LOG_LEVEL_INFO, "should be raw: %s, %d, %f"); + LogPuts(TBOX_LOG_LEVEL_INFO, "should be raw: %s, %d, %f"); LogOutput_Disable(); } diff --git a/modules/eventx/thread_pool.cpp b/modules/eventx/thread_pool.cpp index 6af6ae5c..4696be0c 100644 --- a/modules/eventx/thread_pool.cpp +++ b/modules/eventx/thread_pool.cpp @@ -360,7 +360,7 @@ void ThreadPool::threadProc(ThreadToken thread_token) { RECORD_SCOPE(); - CatchThrow(item->backend_task, true); + CatchThrow(item->backend_task, "tbox::eventx::ThreadPool", true); } auto exec_time_cost = Clock::now() - exec_time_point; diff --git a/modules/eventx/work_thread.cpp b/modules/eventx/work_thread.cpp index d005fa31..fcb04e5d 100644 --- a/modules/eventx/work_thread.cpp +++ b/modules/eventx/work_thread.cpp @@ -236,7 +236,7 @@ void WorkThread::threadProc() { RECORD_SCOPE(); - CatchThrow(item->backend_task, true); + CatchThrow(item->backend_task, "tbox::eventx::WorkThread", true); } auto exec_time_cost = Clock::now() - exec_time_point; diff --git a/modules/jsonrpc/inner_types.h b/modules/jsonrpc/inner_types.h deleted file mode 100644 index c80894f0..00000000 --- a/modules/jsonrpc/inner_types.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef TBOX_JSONRPC_INNER_TYPES_H_20230813 -#define TBOX_JSONRPC_INNER_TYPES_H_20230813 - -namespace tbox { -namespace jsonrpc { - -enum ErrorCode { - kParseError = -32700, - kInvalidRequest = -32600, - kMethodNotFound = -32601, - kInvalidParams = -32602, - kInternalError = -32603, - kRequestTimeout = -32000, -}; - -} -} - -#endif //TBOX_JSONRPC_INNER_TYPES_H_20230813 diff --git a/modules/jsonrpc/protos/header_stream_proto.cpp b/modules/jsonrpc/protos/header_stream_proto.cpp index 50ac2a72..ac2e176d 100644 --- a/modules/jsonrpc/protos/header_stream_proto.cpp +++ b/modules/jsonrpc/protos/header_stream_proto.cpp @@ -55,39 +55,48 @@ void HeaderStreamProto::sendJson(const Json &js) ssize_t HeaderStreamProto::onRecvData(const void *data_ptr, size_t data_size) { TBOX_ASSERT(data_ptr != nullptr); + const uint8_t *byte_ptr = static_cast(data_ptr); + size_t byte_size = data_size; - if (data_size < kHeadSize) - return 0; + for (;;) { + if (byte_size < kHeadSize) + break; - util::Deserializer unpack(data_ptr, data_size); + util::Deserializer unpack(byte_ptr, byte_size); - uint16_t header_magic = 0; - uint32_t content_size = 0; - unpack >> header_magic >> content_size; + uint16_t header_magic = 0; + uint32_t content_size = 0; + unpack >> header_magic >> content_size; - if (header_magic != header_code_) { - LogNotice("head code mismatch"); - return -2; - } + if (header_magic != header_code_) { + LogNotice("head code mismatch"); + return -2; + } - if (content_size + kHeadSize > data_size) //! 不够 - return 0; + if (content_size + kHeadSize > byte_size) //! 不够 + break; - const char *str_ptr = static_cast(unpack.fetchNoCopy(content_size)); - std::string json_text(str_ptr, content_size); + const char *str_ptr = static_cast(unpack.fetchNoCopy(content_size)); + std::string json_text(str_ptr, content_size); - if (is_log_enabled_) - LogTrace("%s recv: %s", log_label_.c_str(), json_text.c_str()); + if (is_log_enabled_) + LogTrace("%s recv: %s", log_label_.c_str(), json_text.c_str()); + + Json js; + bool is_throw = tbox::CatchThrow([&] { js = Json::parse(json_text); }, "tbox::jsonrpc::HeaderStreamProto"); + if (is_throw) { + LogNotice("parse json fail"); + return -1; + } + + onRecvJson(js); - Json js; - bool is_throw = tbox::CatchThrow([&] { js = Json::parse(json_text); }); - if (is_throw) { - LogNotice("parse json fail"); - return -1; + size_t pos = unpack.pos(); + byte_ptr += pos; + byte_size -= pos; } - onRecvJson(js); - return unpack.pos(); + return data_size - byte_size; } } diff --git a/modules/jsonrpc/protos/header_stream_proto_test.cpp b/modules/jsonrpc/protos/header_stream_proto_test.cpp index c1122c9c..041602a4 100644 --- a/modules/jsonrpc/protos/header_stream_proto_test.cpp +++ b/modules/jsonrpc/protos/header_stream_proto_test.cpp @@ -172,5 +172,37 @@ TEST(HeaderStreamProto, RecvUncompleteData) { LogOutput_Disable(); } +//! 测试粘包与不完整包问题 +TEST(HeaderStreamProto, MultiPackages) { + LogOutput_Enable(); + + HeaderStreamProto proto(0xea53); + //proto.setLogEnable(true); + + int count = 0; + proto.setRecvCallback( + [&] (int id, const std::string &method, const Json &js_params) { + if (count == 0) { + EXPECT_EQ(method, "test1"); + } else if (count == 1) { + EXPECT_EQ(method, "test2"); + } + ++count; + }, + [] (int, const Response &) { } + ); + + std::string str_1 = std::string("\xEA\x53\x00\x00\x00\x29", 6) + R"({"id":1,"method":"test1","jsonrpc":"2.0"})"; + std::string str_2 = std::string("\xEA\x53\x00\x00\x00\x35", 6) + R"({"id":2,"method":"test2","jsonrpc":"2.0","params":{}})"; + std::string str_3 = std::string("\xEA\x53\x00\x00\x00\x20", 6) + R"({"jsonrpc":"2.0)"; + std::string str = str_1 + str_2 + str_3; + + EXPECT_EQ(proto.onRecvData(str.c_str(), str.size()), (str_1.size() + str_2.size())); + + EXPECT_EQ(count, 2); + LogOutput_Disable(); +} + + } } diff --git a/modules/jsonrpc/protos/packet_proto.cpp b/modules/jsonrpc/protos/packet_proto.cpp index 29d1dfcb..38e81c7c 100644 --- a/modules/jsonrpc/protos/packet_proto.cpp +++ b/modules/jsonrpc/protos/packet_proto.cpp @@ -58,7 +58,7 @@ ssize_t PacketProto::onRecvData(const void *data_ptr, size_t data_size) LogTrace("%s recv: %s", log_label_.c_str(), json_text.c_str()); Json js; - bool is_throw = tbox::CatchThrow([&] { js = Json::parse(json_text); }); + bool is_throw = tbox::CatchThrow([&] { js = Json::parse(json_text); }, "tbox::jsonrpc::PacketProto"); if (is_throw) { LogNotice("parse json fail"); return -1; diff --git a/modules/jsonrpc/protos/raw_stream_proto.cpp b/modules/jsonrpc/protos/raw_stream_proto.cpp index 2647b5a0..a25c75b0 100644 --- a/modules/jsonrpc/protos/raw_stream_proto.cpp +++ b/modules/jsonrpc/protos/raw_stream_proto.cpp @@ -42,29 +42,36 @@ void RawStreamProto::sendJson(const Json &js) ssize_t RawStreamProto::onRecvData(const void *data_ptr, size_t data_size) { TBOX_ASSERT(data_ptr != nullptr); + const char *str_ptr = static_cast(data_ptr); + size_t str_size = data_size; - if (data_size < 2) - return 0; + for (;;) { + if (str_size < 2) + break; - const char *str_ptr = static_cast(data_ptr); - auto str_len = util::json::FindEndPos(str_ptr, data_size); - if (str_len > 0) { - std::string json_text(str_ptr, str_len); + auto json_len = util::json::FindEndPos(str_ptr, str_size); + if (json_len <= 0) + break; + + std::string json_text(str_ptr, json_len); if (is_log_enabled_) LogTrace("%s recv: %s", log_label_.c_str(), json_text.c_str()); Json js; - bool is_throw = tbox::CatchThrow([&] { js = Json::parse(json_text); }); + bool is_throw = tbox::CatchThrow([&] { js = Json::parse(json_text); }, "tbox::jsonrpc::RawStreamProto"); if (is_throw) { LogNotice("parse json fail"); return -1; } onRecvJson(js); - return str_len; + + str_ptr += json_len; + str_size -= json_len; } - return 0; + + return data_size - str_size; } } diff --git a/modules/jsonrpc/protos/raw_stream_proto_test.cpp b/modules/jsonrpc/protos/raw_stream_proto_test.cpp index fa828ec3..fa6f9ae4 100644 --- a/modules/jsonrpc/protos/raw_stream_proto_test.cpp +++ b/modules/jsonrpc/protos/raw_stream_proto_test.cpp @@ -172,5 +172,36 @@ TEST(RawStreamProto, RecvUncompleteData) { LogOutput_Disable(); } +//! 测试粘包与不完整包问题 +TEST(RawStreamProto, MultiPackages) { + LogOutput_Enable(); + + RawStreamProto proto; + //proto.setLogEnable(true); + + int count = 0; + proto.setRecvCallback( + [&] (int id, const std::string &method, const Json &js_params) { + if (count == 0) { + EXPECT_EQ(method, "test1"); + } else if (count == 1) { + EXPECT_EQ(method, "test2"); + } + ++count; + }, + [] (int, const Response &) { } + ); + + std::string str_1 = R"({"id":1,"method":"test1","jsonrpc":"2.0"})"; + std::string str_2 = R"({"id":2,"method":"test2","jsonrpc":"2.0","params":{}})"; + std::string str_3 = R"({"jsonrpc":"2.0)"; + std::string str = str_1 + str_2 + str_3; + + EXPECT_EQ(proto.onRecvData(str.c_str(), str.size()), (str_1.size() + str_2.size())); + + EXPECT_EQ(count, 2); + LogOutput_Disable(); +} + } } diff --git a/modules/jsonrpc/rpc.cpp b/modules/jsonrpc/rpc.cpp index 9ca464f8..a85afd6f 100644 --- a/modules/jsonrpc/rpc.cpp +++ b/modules/jsonrpc/rpc.cpp @@ -25,7 +25,6 @@ #include #include "proto.h" -#include "inner_types.h" namespace tbox { namespace jsonrpc { @@ -237,7 +236,8 @@ void Rpc::onRecvRequestInt(int int_id, const std::string &method, const Json &js iter->second(int_id, js_params, response); } } else { - respondError(int_id, ErrorCode::kMethodNotFound, "method not found"); + if (int_id != 0) + respondError(int_id, ErrorCode::kMethodNotFound, "method not found"); } } diff --git a/modules/jsonrpc/types.h b/modules/jsonrpc/types.h index 142dc1e3..a2800977 100644 --- a/modules/jsonrpc/types.h +++ b/modules/jsonrpc/types.h @@ -26,22 +26,32 @@ namespace tbox { namespace jsonrpc { +//! 错误码 +enum ErrorCode { + kParseError = -32700, //!< 解析错误 + kInvalidRequest = -32600, //!< 不合法的请求 + kMethodNotFound = -32601, //!< 找不到方法 + kInvalidParams = -32602, //!< 参数不合法 + kInternalError = -32603, //!< 内部异常 + kRequestTimeout = -32000, //!< 请求超时 +}; + //! id 类型:整数、字串 enum class IdType { - kNone, - kInt, - kString + kNone, + kInt, //!< 整数id + kString //!< 字串uuid }; //! 回复 struct Response { - Json js_result; //! 结果 + Json js_result; //! 结果 - //! 错误相关 - struct { - int code = 0; //! 错误码 - std::string message; //! 错误描述 - } error; + //! 错误相关 + struct { + int code = 0; //! 错误码 + std::string message; //! 错误描述 + } error; }; } diff --git a/modules/log/async_file_sink_test.cpp b/modules/log/async_file_sink_test.cpp index d7037a66..9af782a1 100644 --- a/modules/log/async_file_sink_test.cpp +++ b/modules/log/async_file_sink_test.cpp @@ -50,7 +50,7 @@ TEST(AsyncFileSink, AllLevel) ch.setFilePrefix("test"); ch.enable(); ch.enableColor(true); - ch.setLevel("", LOG_LEVEL_TRACE); + ch.setLevel("", TBOX_LOG_LEVEL_TRACE); LogFatal("fatal"); LogErr("err"); diff --git a/modules/log/async_sink.cpp b/modules/log/async_sink.cpp index 7d345f27..7a256646 100644 --- a/modules/log/async_sink.cpp +++ b/modules/log/async_sink.cpp @@ -97,13 +97,13 @@ void AsyncSink::onLogBackEnd(const LogContent &content) //! 开启色彩,显示日志等级 if (enable_color_) { - len = snprintf(buff, sizeof(buff), "\033[%sm", LOG_LEVEL_COLOR_CODE[content.level]); + len = snprintf(buff, sizeof(buff), "\033[%sm", TBOX_LOG_LEVEL_COLOR_CODE[content.level]); append(buff, len); } //! 打印等级、时间戳、线程号、模块名 len = snprintf(buff, sizeof(buff), "%c %s.%06u %ld %s ", - LOG_LEVEL_LEVEL_CODE[content.level], + TBOX_LOG_LEVEL_LEVEL_CODE[content.level], timestamp_str_, content.timestamp.usec, content.thread_id, content.module_id); append(buff, len); diff --git a/modules/log/async_sink_test.cpp b/modules/log/async_sink_test.cpp index 792fd47b..6b9b44e8 100644 --- a/modules/log/async_sink_test.cpp +++ b/modules/log/async_sink_test.cpp @@ -68,7 +68,7 @@ TEST(AsyncSink, AllLevel) ch.enable(); ch.enableColor(true); - ch.setLevel("", LOG_LEVEL_TRACE); + ch.setLevel("", TBOX_LOG_LEVEL_TRACE); LogFatal("fatal"); LogErr("err"); diff --git a/modules/log/async_stdout_sink_test.cpp b/modules/log/async_stdout_sink_test.cpp index 7094f941..10e15fe5 100644 --- a/modules/log/async_stdout_sink_test.cpp +++ b/modules/log/async_stdout_sink_test.cpp @@ -49,7 +49,7 @@ TEST(AsyncStdoutSink, TraceLevel) { AsyncStdoutSink ch; ch.enable(); - ch.setLevel("test.log", LOG_LEVEL_TRACE); + ch.setLevel("test.log", TBOX_LOG_LEVEL_TRACE); cout << "Should print all level" << endl; LogFatal("fatal"); @@ -71,7 +71,7 @@ TEST(AsyncStdoutSink, AllLevel) ch.enable(); ch.enableColor(true); - ch.setLevel("", LOG_LEVEL_TRACE); + ch.setLevel("", TBOX_LOG_LEVEL_TRACE); LogFatal("fatal"); LogErr("err"); @@ -93,7 +93,7 @@ TEST(AsyncStdoutSink, NullString) ch.enable(); LogInfo(nullptr); - LogPuts(LOG_LEVEL_INFO, nullptr); + LogPuts(TBOX_LOG_LEVEL_INFO, nullptr); ch.cleanup(); } @@ -121,7 +121,7 @@ TEST(AsyncStdoutSink, EnableColor) AsyncStdoutSink ch; ch.enable(); ch.enableColor(true); - ch.setLevel("test.log", LOG_LEVEL_TRACE); + ch.setLevel("test.log", TBOX_LOG_LEVEL_TRACE); cout << "Should with color" << endl; LogFatal("fatal"); diff --git a/modules/log/async_syslog_sink_test.cpp b/modules/log/async_syslog_sink_test.cpp index 9e57a3da..8a28bd1e 100644 --- a/modules/log/async_syslog_sink_test.cpp +++ b/modules/log/async_syslog_sink_test.cpp @@ -49,7 +49,7 @@ TEST(AsyncSyslogSink, TraceLevel) { AsyncSyslogSink ch; ch.enable(); - ch.setLevel("test.log", LOG_LEVEL_TRACE); + ch.setLevel("test.log", TBOX_LOG_LEVEL_TRACE); cout << "Should print all level" << endl; LogFatal("fatal"); diff --git a/modules/log/sink.h b/modules/log/sink.h index c0545716..49b6eb74 100644 --- a/modules/log/sink.h +++ b/modules/log/sink.h @@ -67,7 +67,7 @@ class Sink { uint32_t output_id_ = 0; std::map modules_level_; - int default_level_ = LOG_LEVEL_MAX; + int default_level_ = TBOX_LOG_LEVEL_MAX; uint32_t timestamp_sec_ = 0; }; diff --git a/modules/log/sync_stdout_sink.cpp b/modules/log/sync_stdout_sink.cpp index e9ac5654..cd5060d9 100644 --- a/modules/log/sync_stdout_sink.cpp +++ b/modules/log/sync_stdout_sink.cpp @@ -31,10 +31,10 @@ void SyncStdoutSink::onLogFrontEnd(const LogContent *content) //! 开启色彩,显示日志等级 if (enable_color_) - printf("\033[%sm", LOG_LEVEL_COLOR_CODE[content->level]); + printf("\033[%sm", TBOX_LOG_LEVEL_COLOR_CODE[content->level]); //! 打印等级、时间戳、线程号、模块名 - printf("%c %s.%06u %ld %s ", LOG_LEVEL_LEVEL_CODE[content->level], + printf("%c %s.%06u %ld %s ", TBOX_LOG_LEVEL_LEVEL_CODE[content->level], timestamp_str_, content->timestamp.usec, content->thread_id, content->module_id); diff --git a/modules/log/sync_stdout_sink_test.cpp b/modules/log/sync_stdout_sink_test.cpp index 667a7285..0cdb1dd8 100644 --- a/modules/log/sync_stdout_sink_test.cpp +++ b/modules/log/sync_stdout_sink_test.cpp @@ -47,7 +47,7 @@ TEST(SyncStdoutSink, TraceLevel) { SyncStdoutSink ch; ch.enable(); - ch.setLevel("test.log", LOG_LEVEL_TRACE); + ch.setLevel("test.log", TBOX_LOG_LEVEL_TRACE); cout << "Should print all level" << endl; LogFatal("fatal"); @@ -67,7 +67,7 @@ TEST(SyncStdoutSink, AllLevel) ch.enable(); ch.enableColor(true); - ch.setLevel("", LOG_LEVEL_TRACE); + ch.setLevel("", TBOX_LOG_LEVEL_TRACE); LogFatal("fatal"); LogErr("err"); @@ -87,7 +87,7 @@ TEST(SyncStdoutSink, NullString) ch.enable(); LogInfo(nullptr); - LogPuts(LOG_LEVEL_INFO, nullptr); + LogPuts(TBOX_LOG_LEVEL_INFO, nullptr); } TEST(SyncStdoutSink, WillNotPrint) @@ -111,7 +111,7 @@ TEST(SyncStdoutSink, EnableColor) SyncStdoutSink ch; ch.enable(); ch.enableColor(true); - ch.setLevel("test.log", LOG_LEVEL_TRACE); + ch.setLevel("test.log", TBOX_LOG_LEVEL_TRACE); cout << "Should with color" << endl; LogFatal("fatal"); diff --git a/modules/main/CMakeLists.txt b/modules/main/CMakeLists.txt index e84514d9..9db8957b 100644 --- a/modules/main/CMakeLists.txt +++ b/modules/main/CMakeLists.txt @@ -41,7 +41,7 @@ set(TBOX_MAIN_SOURCES error_signals.cpp terminate.cpp misc.cpp - args.cpp + args_parser.cpp module.cpp log.cpp trace.cpp) diff --git a/modules/main/Makefile b/modules/main/Makefile index 17ad00fc..b99bd5da 100644 --- a/modules/main/Makefile +++ b/modules/main/Makefile @@ -36,7 +36,7 @@ CPP_SRC_FILES = \ error_signals.cpp \ terminate.cpp \ misc.cpp \ - args.cpp \ + args_parser.cpp \ module.cpp \ log.cpp \ trace.cpp \ diff --git a/modules/main/args.cpp b/modules/main/args_parser.cpp similarity index 86% rename from modules/main/args.cpp rename to modules/main/args_parser.cpp index e0a645ac..b7869c4c 100644 --- a/modules/main/args.cpp +++ b/modules/main/args_parser.cpp @@ -17,7 +17,7 @@ * project authors may be found in the CONTRIBUTORS.md file in the root * of the source tree. */ -#include "args.h" +#include "args_parser.h" #include #include @@ -38,11 +38,12 @@ string GetAppDescribe(); string GetAppBuildTime(); void GetAppVersion(int &major, int &minor, int &rev, int &build); -Args::Args(Json &conf) : - conf_(conf) +ArgsParser::ArgsParser(Json &conf, Args &args) + : conf_(conf) + , args_(args) { } -bool Args::parse(int argc, const char * const * const argv) +bool ArgsParser::parse(int argc, const char * const * const argv) { bool run = true; //!< 是否需要正常运行 bool print_help = false; //!< 是否需要打印帮助 @@ -97,7 +98,20 @@ bool Args::parse(int argc, const char * const * const argv) } ); - parser.parse(argc, argv); + //! 将 --args 后面的参数全部复制到 args_ 中去 + int args_pos = 0; + for (int i = 1; i < argc; ++i) { + const char* str = argv[i]; + if (args_pos != 0) { + args_.push_back(str); + } else if (::strcmp(str, "--args") == 0) { + args_pos = i; + args_.push_back(proc_name); + } + } + + auto tbox_argc = (args_pos != 0) ? args_pos : argc; + parser.parse(tbox_argc, argv); if (print_tips) printTips(proc_name); @@ -114,12 +128,12 @@ bool Args::parse(int argc, const char * const * const argv) return run; } -void Args::printTips(const std::string &proc_name) +void ArgsParser::printTips(const std::string &proc_name) { cout << "Try '" << proc_name << " --help' for more information." << endl; } -void Args::printHelp(const std::string &proc_name) +void ArgsParser::printHelp(const std::string &proc_name) { cout << "Usage: " << proc_name << " [OPTION]" << endl << GetAppDescribe() << endl << endl @@ -130,6 +144,7 @@ void Args::printHelp(const std::string &proc_name) << " -s KEY=VALUE set config field" << endl << " -p display config" << endl << " -n don't run" << endl + << " --args start application's arguments" << endl << endl << "EXAMPLE" << endl << " " << proc_name << endl @@ -139,10 +154,11 @@ void Args::printHelp(const std::string &proc_name) << " " << proc_name << R"( -s 'log.filelog.enable=true' -s 'log.filelog.path="/tmp/"')" << endl << " " << proc_name << R"( -s 'log.filelog={"enable":true,"path":"/tmp/"}')" << endl << " " << proc_name << R"( -c somewhere/conf.json -s 'thread_pool.min=2')" << endl + << " " << proc_name << R"( -c xxx.json --args abc 123)" << endl << endl; } -void Args::printVersion() +void ArgsParser::printVersion() { int major, minor, rev, build; GetTboxVersion(major, minor, rev); @@ -154,7 +170,7 @@ void Args::printVersion() } -bool Args::load(const std::string &config_filename) +bool ArgsParser::load(const std::string &config_filename) { try { auto js_patch = util::json::LoadDeeply(config_filename); @@ -195,7 +211,7 @@ Json& BuildJsonByKey(const std::string &key, Json &js_root) return *p_node; } -bool Args::set(const std::string &set_string) +bool ArgsParser::set(const std::string &set_string) { vector str_vec; if (util::string::Split(set_string, "=", str_vec) != 2) { diff --git a/modules/main/args.h b/modules/main/args_parser.h similarity index 84% rename from modules/main/args.h rename to modules/main/args_parser.h index 77419bb0..a7cd8d61 100644 --- a/modules/main/args.h +++ b/modules/main/args_parser.h @@ -18,9 +18,9 @@ * of the source tree. */ /** - * 本文件定义 Args 类 + * 本文件定义 ArgsParser 类 * - * Args 类用于解释程序的命令参数,输出程序运行的配置Json数据。 + * ArgsParser 类用于解释程序的命令参数,输出程序运行的配置Json数据。 * * 参数: * @@ -41,17 +41,18 @@ * myproc -v * myproc --version */ -#ifndef TBOX_MAIN_ARGS_H_20211229 -#define TBOX_MAIN_ARGS_H_20211229 +#ifndef TBOX_MAIN_ARGS_PARSER_H_20211229 +#define TBOX_MAIN_ARGS_PARSER_H_20211229 #include +#include "context.h" namespace tbox { namespace main { -class Args { +class ArgsParser { public: - Args(Json &conf); + ArgsParser(Json &conf, Args &args); /** * 解析参数 @@ -74,9 +75,10 @@ class Args { private: Json &conf_; + Args &args_; }; } } -#endif //TBOX_MAIN_ARGS_H_20211229 +#endif //TBOX_MAIN_ARGS_PARSER_H_20211229 diff --git a/modules/main/context.h b/modules/main/context.h index 728ad432..0d3da20b 100644 --- a/modules/main/context.h +++ b/modules/main/context.h @@ -32,6 +32,8 @@ namespace tbox { namespace main { +using Args = std::vector; + //! 进程上下文 class Context { public: @@ -44,6 +46,8 @@ class Context { virtual std::chrono::milliseconds running_time() const = 0; virtual std::chrono::system_clock::time_point start_time_point() const = 0; + + virtual const Args& args() const = 0; }; } diff --git a/modules/main/context_imp.cpp b/modules/main/context_imp.cpp index f154465b..5588d218 100644 --- a/modules/main/context_imp.cpp +++ b/modules/main/context_imp.cpp @@ -111,11 +111,12 @@ void ContextImp::fillDefaultConfig(Json &cfg) const cfg["thread_pool"] = R"({"min":0, "max":1})"_json; } -bool ContextImp::initialize(const char* proc_name, const Json &cfg, Module *module) +bool ContextImp::initialize(const char* proc_name, const Json &cfg, const Args &args, Module *module) { TBOX_ASSERT(module != nullptr); module_ = module; js_conf_ = &cfg; + wp_args_ = &args; if (util::json::HasObjectField(cfg, "loop")) { auto &js_loop = cfg["loop"]; @@ -484,9 +485,9 @@ void ContextImp::initShell() } } + auto dump_node = wp_nodes->createDirNode("dump directory"); + wp_nodes->mountNode(wp_nodes->rootNode(), dump_node, "dump"); { - auto dump_node = wp_nodes->createDirNode("dump directory"); - wp_nodes->mountNode(wp_nodes->rootNode(), dump_node, "dump"); auto func_node = wp_nodes->createFuncNode( [this] (const Session &s, const Args &a) { Json js; @@ -506,6 +507,21 @@ void ContextImp::initShell() wp_nodes->mountNode(dump_node, func_node, "apps"); wp_nodes->mountNode(dump_node, func_node, "conf"); } + { + auto func_node = wp_nodes->createFuncNode( + [this] (const Session &s, const Args &) { + std::ostringstream oss; + auto &args = *wp_args_; + for (size_t i = 0; i < args.size(); ++i) + oss << '[' << i << "]:" << args.at(i) << "\r\n"; + oss << "\r\n"; + s.send(oss.str()); + }, + "Dump args" + ); + + wp_nodes->mountNode(dump_node, func_node, "args"); + } } } diff --git a/modules/main/context_imp.h b/modules/main/context_imp.h index 51edd0ea..720ad600 100644 --- a/modules/main/context_imp.h +++ b/modules/main/context_imp.h @@ -40,7 +40,7 @@ class ContextImp : public Context { void fillDefaultConfig(Json &cfg) const; - bool initialize(const char *proc_name, const Json &cfg, Module *module); + bool initialize(const char *proc_name, const Json &cfg, const Args &args, Module *module); bool start(); void stop(); void cleanup(); @@ -56,6 +56,8 @@ class ContextImp : public Context { virtual std::chrono::milliseconds running_time() const override; virtual std::chrono::system_clock::time_point start_time_point() const override; + virtual const Args& args() const override { return *wp_args_; } + protected: bool initLoop(const Json &js); bool initThreadPool(const Json &js); @@ -81,6 +83,7 @@ class ContextImp : public Context { const Module *module_ = nullptr; const Json *js_conf_ = nullptr; + const Args *wp_args_ = nullptr; }; } diff --git a/modules/main/log.cpp b/modules/main/log.cpp index 408c3d33..8b407f8a 100644 --- a/modules/main/log.cpp +++ b/modules/main/log.cpp @@ -393,8 +393,8 @@ void Log::installShellForSink(log::Sink &sink, terminal::NodeToken parent_node, oss << "level must be number\r\n"; break; } - if (level < 0 || level > LOG_LEVEL_TRACE) { - oss << "level range: [0-" << LOG_LEVEL_TRACE << "]\r\n"; + if (level < 0 || level > TBOX_LOG_LEVEL_TRACE) { + oss << "level range: [0-" << TBOX_LOG_LEVEL_TRACE << "]\r\n"; break; } diff --git a/modules/main/main.h b/modules/main/main.h index 39443a13..23318eb9 100644 --- a/modules/main/main.h +++ b/modules/main/main.h @@ -79,6 +79,11 @@ void Stop(); */ void GetVersion(int &major, int &minor, int &rev, int &build); +/** + * 给自身发送停止请求 + */ +void RaiseStopSignal(); + ////////////////////////////////////////////////////////////////////////// // 以下是需要开发者去实现的 ////////////////////////////////////////////////////////////////////////// diff --git a/modules/main/misc.cpp b/modules/main/misc.cpp index 59040b28..b90fad63 100644 --- a/modules/main/misc.cpp +++ b/modules/main/misc.cpp @@ -116,5 +116,11 @@ void AbnormalExit() std::abort(); } +void RaiseStopSignal() +{ + LogInfo("App requires stop process"); + ::raise(SIGTERM); +} + } } diff --git a/modules/main/run_in_backend.cpp b/modules/main/run_in_backend.cpp index 6f85d64c..671307cd 100644 --- a/modules/main/run_in_backend.cpp +++ b/modules/main/run_in_backend.cpp @@ -32,7 +32,7 @@ #include "module.h" #include "context_imp.h" -#include "args.h" +#include "args_parser.h" #include "log.h" #include "trace.h" @@ -58,6 +58,7 @@ struct Runtime { ContextImp ctx; Module apps; Json js_conf; + Args args; util::PidFile pid_file; int exit_wait_sec = 1; @@ -127,8 +128,9 @@ bool Start(int argc, char **argv) auto &ctx = _runtime->ctx; auto &apps = _runtime->apps; auto &js_conf = _runtime->js_conf; + auto &args = _runtime->args; - Args args(js_conf); + ArgsParser args_parser(js_conf, args); Trace trace; log.fillDefaultConfig(js_conf); @@ -138,7 +140,7 @@ bool Start(int argc, char **argv) FillAppDefaultConfig(js_conf); apps.fillDefaultConfig(js_conf); - if (!args.parse(argc, argv)) + if (!args_parser.parse(argc, argv)) return false; std::string pid_filename; @@ -171,7 +173,7 @@ bool Start(int argc, char **argv) std::this_thread::sleep_for(std::chrono::seconds(1)); }; - if (ctx.initialize(argv[0], js_conf, &apps)) { + if (ctx.initialize(argv[0], js_conf, args, &apps)) { if (apps.initialize(js_conf)) { if (ctx.start()) { //! 启动所有应用 if (apps.start()) { diff --git a/modules/main/run_in_frontend.cpp b/modules/main/run_in_frontend.cpp index 56cce635..5db38003 100644 --- a/modules/main/run_in_frontend.cpp +++ b/modules/main/run_in_frontend.cpp @@ -32,7 +32,7 @@ #include "module.h" #include "context_imp.h" -#include "args.h" +#include "args_parser.h" #include "log.h" #include "trace.h" @@ -110,8 +110,10 @@ int Main(int argc, char **argv) Module apps("", ctx); RegisterApps(apps, ctx); + Args args; Json js_conf; - Args args(js_conf); + ArgsParser args_parser(js_conf, args); + Trace trace; log.fillDefaultConfig(js_conf); @@ -121,7 +123,7 @@ int Main(int argc, char **argv) FillAppDefaultConfig(js_conf); apps.fillDefaultConfig(js_conf); - if (!args.parse(argc, argv)) + if (!args_parser.parse(argc, argv)) return 0; std::string pid_filename; @@ -158,7 +160,7 @@ int Main(int argc, char **argv) std::this_thread::sleep_for(std::chrono::seconds(1)); }; - if (ctx.initialize(argv[0], js_conf, &apps)) { + if (ctx.initialize(argv[0], js_conf, args, &apps)) { if (apps.initialize(js_conf)) { if (ctx.start() && apps.start()) { //! 启动所有应用 RunInFrontend(ctx, apps, exit_wait_sec); diff --git a/modules/mqtt/client.cpp b/modules/mqtt/client.cpp index c8d73341..5d7c1012 100644 --- a/modules/mqtt/client.cpp +++ b/modules/mqtt/client.cpp @@ -584,18 +584,18 @@ void Client::onMessage(const struct mosquitto_message *msg) void Client::onLog(int level, const char *str) { - auto new_level = LOG_LEVEL_DEBUG; + auto new_level = TBOX_LOG_LEVEL_DEBUG; switch (level & 0x1F) { case MOSQ_LOG_ERR: - new_level = LOG_LEVEL_ERROR; + new_level = TBOX_LOG_LEVEL_ERROR; break; case MOSQ_LOG_WARNING: - new_level = LOG_LEVEL_WARN; + new_level = TBOX_LOG_LEVEL_WARN; break; case MOSQ_LOG_NOTICE: - new_level = LOG_LEVEL_NOTICE; + new_level = TBOX_LOG_LEVEL_NOTICE; break; - default:; //! regard MOSQ_LOG_INFO as LOG_LEVEL_DEBUG + default:; //! regard MOSQ_LOG_INFO as TBOX_LOG_LEVEL_DEBUG } LogPrintfFunc("mosq", nullptr, nullptr, 0, new_level, 0, str); } diff --git a/modules/util/fs.cpp b/modules/util/fs.cpp index 85e95dc8..6d2b8903 100644 --- a/modules/util/fs.cpp +++ b/modules/util/fs.cpp @@ -73,10 +73,10 @@ bool ReadStringFromTextFile(const std::string &filename, std::string &content) std::istreambuf_iterator()); return true; } else { - LogWarn("open failed, %s", filename.c_str()); + LogNotice("open failed, %s", filename.c_str()); } } catch (const exception &e) { - LogWarn("catch exception: %s", e.what()); + LogNotice("catch exception: %s", e.what()); } return false; } @@ -94,10 +94,10 @@ bool ReadEachLineFromTextFile(const std::string &filename, const std::function &names) if (dp == nullptr) { // 无法打开目录,直接结束 if (errno == ENOENT) { - LogWarn("directory %s does not exist", dir.c_str()); + LogNotice("directory %s does not exist", dir.c_str()); } else { - LogWarn("open directory %s fail, errno:%d, %s", dir.c_str(), errno, strerror(errno)); + LogNotice("open directory %s fail, errno:%d, %s", dir.c_str(), errno, strerror(errno)); } return false; } @@ -492,7 +492,7 @@ bool Rename(const std::string &old_name, const std::string &new_name) if (ret == 0) return true; - LogWarn("rename '%s' to '%s' fail, errno:%d (%s)", + LogNotice("rename '%s' to '%s' fail, errno:%d (%s)", old_name.c_str(), new_name.c_str(), errno, strerror(errno)); return false; } diff --git a/modules/util/json.cpp b/modules/util/json.cpp index 384ec0a3..1bc2b153 100644 --- a/modules/util/json.cpp +++ b/modules/util/json.cpp @@ -171,7 +171,7 @@ bool Parse(const std::string &text, Json &js) noexcept { return !CatchThrow([&] { js = Json::parse(text); - }); + }, "tbox::util::json::Parse"); } Json Load(const std::string &filename) diff --git a/version.mk b/version.mk index 88bdeab4..f897c12c 100644 --- a/version.mk +++ b/version.mk @@ -21,4 +21,4 @@ # TBOX版本号 TBOX_VERSION_MAJOR := 1 TBOX_VERSION_MINOR := 13 -TBOX_VERSION_REVISION := 3 +TBOX_VERSION_REVISION := 9