Copilot commented on code in PR #3691:
URL: https://github.com/apache/brpc/pull/3691#discussion_r4425850870


##########
src/brpc/versioned_ref_with_id.h:
##########
@@ -628,18 +648,24 @@ int VersionedRefWithId<T>::Dereference() {
 
 template<typename T>
 void VersionedRefWithId<T>::Revive(int32_t at_least_nref) {
+    AdditionalRefStatus expect = ADDITIONAL_REF_RELEASED_ON_FAILURE;
+    if (!_additional_ref_status.compare_exchange_strong(
+            expect, ADDITIONAL_REF_REVIVING,
+            butil::memory_order_relaxed,
+            butil::memory_order_relaxed)) {
+        CHECK_EQ(ADDITIONAL_REF_RELEASED, expect);

Review Comment:
   Revive() assumes the only possible CAS-failure state is 
ADDITIONAL_REF_RELEASED, but compare_exchange_strong writes the observed 
current value into `expect`. If Revive() can be called when the status is 
ADDITIONAL_REF_USING (or still ADDITIONAL_REF_REVIVING due to a concurrent 
reviver), this CHECK will crash the process. Consider handling 
non-RELEASED_ON_FAILURE states as a no-op (e.g., return when expect is 
ADDITIONAL_REF_RELEASED or ADDITIONAL_REF_USING, and optionally yield/retry 
when expect is ADDITIONAL_REF_REVIVING), rather than CHECKing.



##########
test/brpc_channel_unittest.cpp:
##########
@@ -3977,6 +3996,31 @@ class CountingSubChannel : public brpc::Channel {
 };
 int CountingSubChannel::s_alive = 0;
 
+TEST_F(ChannelTest, selective_channel_removal_prevents_revival) {
+    brpc::SelectiveChannel channel;
+    ASSERT_EQ(0, channel.Init("rr", nullptr));
+    brpc::SelectiveChannel::ChannelHandle handle;
+    ASSERT_EQ(0, channel.AddChannel(new CountingSubChannel, &handle));
+    ASSERT_EQ(1, CountingSubChannel::s_alive);
+    brpc::SocketUniquePtr ptr;
+    ASSERT_EQ(0, brpc::Socket::Address(handle.id, &ptr));
+
+    // Keep the HC reference but disable automatic scheduling: the retained
+    // pointer below simulates the health check task resuming after removal.
+    ptr->_is_hc_related_ref_held = false;
+    EXPECT_EQ(0, ptr->SetFailed());
+    ptr->_is_hc_related_ref_held = true;
+    channel.RemoveAndDestroyChannel(handle);
+    EXPECT_FALSE(ptr->HCEnabled());
+    ptr->Revive(1);
+    EXPECT_TRUE(ptr->Failed());
+    EXPECT_EQ(1, ptr->nref());
+    // Also clean up the leaked additional reference if this test regresses.

Review Comment:
   The test directly mutates an internal socket field 
(`_is_hc_related_ref_held`) to simulate HC scheduling behavior. This tightly 
couples the test to private/internal implementation details and makes future 
refactors riskier. Prefer using a public test hook (e.g., a helper API to 
pause/resume HC scheduling) or a fixture-level mechanism to disable scheduling 
without reaching into internal fields.



##########
test/brpc_channel_unittest.cpp:
##########
@@ -2576,6 +2576,25 @@ TEST_F(ChannelTest, init_using_unknown_naming_service) {
     ASSERT_EQ(-1, channel.Init("unknown://unknown", "unknown", nullptr));
 }
 
+TEST_F(ChannelTest, selective_channel_invalid_load_balancer) {
+    GFLAGS_NAMESPACE::FlagSaver flag_saver;
+#if !BRPC_WITH_GLOG
+    // Invalid configuration must return an error even when fatal logs abort.
+    ASSERT_FALSE(GFLAGS_NAMESPACE::SetCommandLineOption(
+                     "crash_on_fatal_log", "true").empty());
+#endif

Review Comment:
   This test configures `crash_on_fatal_log` (and the comment references fatal 
logs), but the PR also changes SharedLoadBalancer::Init() to LOG(ERROR) instead 
of LOG(FATAL). That makes the comment and the flag toggling 
misleading/redundant. Suggest updating the comment to reflect the new behavior 
and removing the flag manipulation unless some remaining initialization path 
still produces fatal logs that this test is intended to guard against.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to