From 5d93b5ef2df88ec2ea718f95762c11ca48f09bd6 Mon Sep 17 00:00:00 2001 From: Hevake Date: Fri, 14 Nov 2025 22:08:48 +0800 Subject: [PATCH 1/4] =?UTF-8?q?feat(jsonrpc):=20=E6=B7=BB=E5=8A=A0Rpc::cle?= =?UTF-8?q?ar()=E6=96=B9=E6=B3=95=EF=BC=8C=E7=94=A8=E4=BA=8E=E6=B8=85?= =?UTF-8?q?=E9=99=A4=E7=BC=93=E5=AD=98=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/eventx/timeout_monitor.hpp | 1 + modules/eventx/timeout_monitor_impl.hpp | 7 ++++- modules/eventx/timeout_monitor_test.cpp | 33 +++++++++++++++++++++++ modules/jsonrpc/rpc.cpp | 11 ++++++++ modules/jsonrpc/rpc.h | 3 +++ modules/jsonrpc/rpc_int_test.cpp | 36 +++++++++++++++++++++++++ 6 files changed, 90 insertions(+), 1 deletion(-) diff --git a/modules/eventx/timeout_monitor.hpp b/modules/eventx/timeout_monitor.hpp index 86309e1..7359bf8 100644 --- a/modules/eventx/timeout_monitor.hpp +++ b/modules/eventx/timeout_monitor.hpp @@ -57,6 +57,7 @@ class TimeoutMonitor { void setCallback(const Callback &cb) { cb_ = cb; } void add(const T &value); + void clear(); void cleanup(); diff --git a/modules/eventx/timeout_monitor_impl.hpp b/modules/eventx/timeout_monitor_impl.hpp index 74fd93d..a93d8c7 100644 --- a/modules/eventx/timeout_monitor_impl.hpp +++ b/modules/eventx/timeout_monitor_impl.hpp @@ -74,7 +74,7 @@ void TimeoutMonitor::add(const T &value) } template -void TimeoutMonitor::cleanup() +void TimeoutMonitor::clear() { if (curr_item_ == nullptr) return; @@ -92,7 +92,12 @@ void TimeoutMonitor::cleanup() delete item; item = next; } +} +template +void TimeoutMonitor::cleanup() +{ + clear(); cb_ = nullptr; } diff --git a/modules/eventx/timeout_monitor_test.cpp b/modules/eventx/timeout_monitor_test.cpp index 98ae83f..626b992 100644 --- a/modules/eventx/timeout_monitor_test.cpp +++ b/modules/eventx/timeout_monitor_test.cpp @@ -55,6 +55,39 @@ TEST(TimeoutMonitor, Basic) EXPECT_TRUE(run); } +//! 测试中途clear()的操作,观察有没有被误触发 +TEST(TimeoutMonitor, Clear) +{ + auto sp_loop = Loop::New(); + auto sp_timer = sp_loop->newTimerEvent(); + SetScopeExitAction( + [=] { + delete sp_loop; + delete sp_timer; + } + ); + sp_timer->initialize(std::chrono::milliseconds(50), Event::Mode::kOneshot); + + TimeoutMonitor tm(sp_loop); + tm.initialize(milliseconds(10), 10); + + sp_timer->setCallback([&] { tm.clear(); }); + sp_timer->enable(); + + bool run = false; + tm.setCallback([&] (int value) { + run = true; + }); + + tm.add(100); + tm.add(101); + + sp_loop->exitLoop(milliseconds(120)); + sp_loop->runLoop(); + + EXPECT_FALSE(run); +} + } } } diff --git a/modules/jsonrpc/rpc.cpp b/modules/jsonrpc/rpc.cpp index 34e6fc7..abaabb4 100644 --- a/modules/jsonrpc/rpc.cpp +++ b/modules/jsonrpc/rpc.cpp @@ -209,6 +209,17 @@ void Rpc::setStrIdGenFunc(StrIdGenFunc &&func) } } +void Rpc::clear() +{ + int_id_alloc_ = 0; + request_callback_.clear(); + tobe_respond_.clear(); + request_timeout_.clear(); + respond_timeout_.clear(); + int_to_str_map_.clear(); + str_to_int_map_.clear(); +} + void Rpc::onRecvRequestInt(int int_id, const std::string &method, const Json &js_params) { RECORD_SCOPE(); diff --git a/modules/jsonrpc/rpc.h b/modules/jsonrpc/rpc.h index e8f7f4f..5889f46 100644 --- a/modules/jsonrpc/rpc.h +++ b/modules/jsonrpc/rpc.h @@ -92,6 +92,9 @@ class Rpc { //! 设置string id生成函数,默认为UUIDv4 void setStrIdGenFunc(StrIdGenFunc &&func); + //! 清除缓存数据,恢复到没有收发数据之前的状态 + void clear(); + protected: void onRecvRequestInt(int int_id, const std::string &method, const Json ¶ms); void onRecvRespondInt(int int_id, int errcode, const Json &result); diff --git a/modules/jsonrpc/rpc_int_test.cpp b/modules/jsonrpc/rpc_int_test.cpp index 1ef0974..854381f 100644 --- a/modules/jsonrpc/rpc_int_test.cpp +++ b/modules/jsonrpc/rpc_int_test.cpp @@ -203,5 +203,41 @@ TEST(RpcInt, RequestTimeout) { EXPECT_TRUE(is_method_cb_invoke); } +//! 发了一个请求,在回复之前被clear +TEST(RpcInt, Clear) { + auto loop = event::Loop::New(); + auto timer = loop->newTimerEvent(); + SetScopeExitAction( + [=] { + delete loop; + delete timer; + } + ); + + timer->initialize(std::chrono::milliseconds(50), event::Event::Mode::kOneshot); + + Rpc rpc(loop); + RawStreamProto proto; + rpc.initialize(&proto, 1); + + timer->setCallback([&] { rpc.clear(); }); + timer->enable(); + + bool is_method_cb_invoke = false; + loop->run( + [&] { + rpc.request("A", Json(), + [&] (int, const Json &) { + is_method_cb_invoke = true; + } + ); + } + ); + loop->exitLoop(std::chrono::milliseconds(1001)); + loop->runLoop(); + + EXPECT_FALSE(is_method_cb_invoke); +} + } } -- Gitee From 3c801512880e8f158aa9fa094d436b5eff7aaa9c Mon Sep 17 00:00:00 2001 From: Hevake Date: Fri, 14 Nov 2025 22:27:12 +0800 Subject: [PATCH 2/4] =?UTF-8?q?fix(jsonrpc):=20=E4=BF=AE=E5=A4=8DTimeoutMo?= =?UTF-8?q?nitor=E5=87=BA=E7=8E=B0=E5=B4=A9=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/eventx/timeout_monitor_impl.hpp | 40 +++++++++++++++---------- modules/jsonrpc/rpc_int_test.cpp | 2 +- 2 files changed, 26 insertions(+), 16 deletions(-) diff --git a/modules/eventx/timeout_monitor_impl.hpp b/modules/eventx/timeout_monitor_impl.hpp index a93d8c7..aa7c10c 100644 --- a/modules/eventx/timeout_monitor_impl.hpp +++ b/modules/eventx/timeout_monitor_impl.hpp @@ -76,29 +76,39 @@ void TimeoutMonitor::add(const T &value) template void TimeoutMonitor::clear() { - if (curr_item_ == nullptr) - return; - - if (value_number_ > 0) + if (value_number_ > 0) { + value_number_ = 0; sp_timer_->disable(); - value_number_ = 0; - - PollItem *item = curr_item_->next; - curr_item_->next = nullptr; - curr_item_ = nullptr; - while (item != nullptr) { - auto next = item->next; - delete item; - item = next; + PollItem *item = curr_item_; + do { + item->items.clear(); + item = item->next; + } while (item != curr_item_); } } template void TimeoutMonitor::cleanup() { - clear(); - cb_ = nullptr; + if (curr_item_ == nullptr) + return; + + if (value_number_ > 0) + sp_timer_->disable(); + value_number_ = 0; + + PollItem *item = curr_item_->next; + curr_item_->next = nullptr; + curr_item_ = nullptr; + + while (item != nullptr) { + auto next = item->next; + delete item; + item = next; + } + + cb_ = nullptr; } template diff --git a/modules/jsonrpc/rpc_int_test.cpp b/modules/jsonrpc/rpc_int_test.cpp index 6018c28..b17636c 100644 --- a/modules/jsonrpc/rpc_int_test.cpp +++ b/modules/jsonrpc/rpc_int_test.cpp @@ -229,7 +229,7 @@ TEST(RpcInt, Clear) { loop->run( [&] { rpc.request("A", Json(), - [&] (int, const Json &) { + [&] (const Response &r) { is_method_cb_invoke = true; } ); -- Gitee From 09d06604206b4d16a4fa07f905bcb2cea8f92473 Mon Sep 17 00:00:00 2001 From: Hevake Date: Sun, 16 Nov 2025 16:50:38 +0800 Subject: [PATCH 3/4] =?UTF-8?q?fix(jsonrpc):=20=E5=9C=A8Proto=E4=B8=AD?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=9E=90=E6=9E=84=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/jsonrpc/proto.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/jsonrpc/proto.h b/modules/jsonrpc/proto.h index df07912..118f6b2 100644 --- a/modules/jsonrpc/proto.h +++ b/modules/jsonrpc/proto.h @@ -36,6 +36,8 @@ class Proto { using RecvRespondStrCallback = std::function; using SendDataCallback = std::function; + virtual ~Proto() {} + void setRecvCallback(RecvRequestIntCallback &&req_cb, RecvRespondIntCallback &&rsp_cb); void setRecvCallback(RecvRequestStrCallback &&req_cb, RecvRespondStrCallback &&rsp_cb); void setSendCallback(SendDataCallback &&cb); -- Gitee From 60a4c45d76af2a2122648e39fb9779c280426b55 Mon Sep 17 00:00:00 2001 From: Hevake Lee Date: Sun, 16 Nov 2025 22:54:26 +0800 Subject: [PATCH 4/4] =?UTF-8?q?tidy(eventx):=20=E8=B0=83=E6=95=B4=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/eventx/timeout_monitor_impl.hpp | 29 +++++++++++++------------ modules/eventx/timeout_monitor_test.cpp | 4 ++-- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/modules/eventx/timeout_monitor_impl.hpp b/modules/eventx/timeout_monitor_impl.hpp index aa7c10c..0131c47 100644 --- a/modules/eventx/timeout_monitor_impl.hpp +++ b/modules/eventx/timeout_monitor_impl.hpp @@ -91,24 +91,25 @@ void TimeoutMonitor::clear() template void TimeoutMonitor::cleanup() { - if (curr_item_ == nullptr) - return; + if (curr_item_ == nullptr) + return; - if (value_number_ > 0) - sp_timer_->disable(); - value_number_ = 0; + if (value_number_ > 0) { + sp_timer_->disable(); + value_number_ = 0; + } - PollItem *item = curr_item_->next; - curr_item_->next = nullptr; - curr_item_ = nullptr; + PollItem *item = curr_item_->next; + curr_item_->next = nullptr; + curr_item_ = nullptr; - while (item != nullptr) { - auto next = item->next; - delete item; - item = next; - } + while (item != nullptr) { + auto next = item->next; + delete item; + item = next; + } - cb_ = nullptr; + cb_ = nullptr; } template diff --git a/modules/eventx/timeout_monitor_test.cpp b/modules/eventx/timeout_monitor_test.cpp index 626b992..8e4205b 100644 --- a/modules/eventx/timeout_monitor_test.cpp +++ b/modules/eventx/timeout_monitor_test.cpp @@ -66,10 +66,10 @@ TEST(TimeoutMonitor, Clear) delete sp_timer; } ); - sp_timer->initialize(std::chrono::milliseconds(50), Event::Mode::kOneshot); + sp_timer->initialize(std::chrono::milliseconds(25), Event::Mode::kOneshot); TimeoutMonitor tm(sp_loop); - tm.initialize(milliseconds(10), 10); + tm.initialize(milliseconds(10), 3); sp_timer->setCallback([&] { tm.clear(); }); sp_timer->enable(); -- Gitee