فهرست منبع

ZOOKEEPER-562. c client can flood server with pings if tcp send queue filled. (ben reed via mahadev)

git-svn-id: https://svn.apache.org/repos/asf/hadoop/zookeeper/trunk@831088 13f79535-47bb-0310-9956-ffa450edef68
Mahadev Konar 15 سال پیش
والد
کامیت
e9a7606bb0
3فایلهای تغییر یافته به همراه27 افزوده شده و 2 حذف شده
  1. 3 0
      CHANGES.txt
  2. 1 1
      src/c/src/zookeeper.c
  3. 23 1
      src/c/tests/TestOperations.cc

+ 3 - 0
CHANGES.txt

@@ -97,6 +97,9 @@ BUGFIXES:
 
   ZOOKEEPER-563. ant test for recipes is broken. (mahadev via phunt)
  
+  ZOOKEEPER-562. c client can flood server with pings if tcp send queue
+  filled. (ben reed via mahadev)
+
 IMPROVEMENTS:
   ZOOKEEPER-473. cleanup junit tests to eliminate false positives due to
   "socket reuse" and failure to close client (phunt via mahadev)

+ 1 - 1
src/c/src/zookeeper.c

@@ -1402,7 +1402,7 @@ static struct timeval get_timeval(int interval)
         // a PING
         if (zh->state==ZOO_CONNECTED_STATE) {
             send_to = zh->recv_timeout/3 - idle_send;
-            if (send_to <= 0) {
+            if (send_to <= 0 && zh->sent_requests.head==0) {
 //                LOG_DEBUG(("Sending PING to %s (exceeded idle by %dms)",
 //                                format_current_endpoint_info(zh),-send_to));
                 int rc=send_ping(zh);

+ 23 - 1
src/c/tests/TestOperations.cc

@@ -279,6 +279,27 @@ public:
         // only one ping so far?
         CPPUNIT_ASSERT_EQUAL(1,zkServer.pingCount_);
         CPPUNIT_ASSERT(timeMock==zh->last_recv);
+
+        // Round 4
+        // make sure that a ping is not sent if something is outstanding
+        AsyncGetOperationCompletion res1;
+        rc=zoo_aget(zh,"/x/y/1",0,asyncCompletion,&res1);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
+        rc=zookeeper_interest(zh,&fd,&interest,&tv);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
+        timeMock.tick(tv);  
+        rc=zookeeper_interest(zh,&fd,&interest,&tv);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
+        rc=zookeeper_process(zh,interest);
+        CPPUNIT_ASSERT_EQUAL((int)ZNOTHING,rc);
+        rc=zookeeper_interest(zh,&fd,&interest,&tv);
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
+        // pseudo-sleep for a short while (10 ms)
+        timeMock.millitick(10);
+        rc=zookeeper_process(zh,interest);
+        CPPUNIT_ASSERT_EQUAL((int)ZNOTHING,rc);
+        // only one ping so far?
+        CPPUNIT_ASSERT_EQUAL(1,zkServer.pingCount_);
     }
 
     // simulate a watch arriving right before a ping is due
@@ -346,6 +367,7 @@ public:
         
         // queue up a request; keep it pending (as if the server is busy or has died)
         AsyncGetOperationCompletion res1;
+        zkServer.addOperationResponse(new ZooGetResponse("2",1));
         int rc=zoo_aget(zh,"/x/y/1",0,asyncCompletion,&res1);
 
         int fd=0;
@@ -358,7 +380,7 @@ public:
         CPPUNIT_ASSERT_EQUAL((int)ZOK,rc);
         // no delay -- the socket is writable
         rc=zookeeper_process(zh,interest);
-        CPPUNIT_ASSERT_EQUAL((int)ZNOTHING,rc); // ZNOTHING -- no response yet
+        CPPUNIT_ASSERT_EQUAL((int)ZOK,rc); 
         
         // Round 2.
         // what's next?