testing: improve sanitizer handling
[awesomized/libmemcached] / testing / lib / Cluster.cpp
index 5d2ab42a7eb3e5f42fbf18078b3099e086d99bb1..c3c625cf04eb225069a08d4b5f732ea68132eade 100644 (file)
@@ -1,10 +1,11 @@
 #include "Cluster.hpp"
+#include "Retry.hpp"
 
 #include <sys/wait.h>
 
-Cluster::Cluster(Server &&serv, uint16_t cnt)
+Cluster::Cluster(Server serv, uint16_t cnt)
 : count{cnt}
-, proto{forward<Server>(serv)}
+, proto{move(serv)}
 {
   if (!cnt) {
     count = thread::hardware_concurrency()/2 ?: 4;
@@ -33,10 +34,7 @@ bool Cluster::start() {
   bool started = true;
 
   for (auto &server : cluster) {
-    auto pid = server.start();
-    if (pid.has_value()) {
-      pids[*pid] = &server;
-    } else {
+    if (!startServer(server)) {
       started = false;
     }
   }
@@ -46,6 +44,7 @@ bool Cluster::start() {
 
 void Cluster::stop() {
   for (auto &server : cluster) {
+    server.drain();
     // no cookies for memcached; TERM is just too slow
     server.signal(SIGKILL);
   }
@@ -62,23 +61,38 @@ bool Cluster::isStopped() {
 
 bool Cluster::isListening() {
   for (auto &server : cluster) {
-    if (!server.isListening()) {
-      // zombie?
-      auto old_pid = server.getPid();
-      if (server.tryWait()) {
-        pids.erase(old_pid);
-        auto pid = server.start();
-        if (pid.has_value()) {
-          pids[*pid] = &server;
+    Retry server_is_listening{[&] {
+      if (!server.isListening()) {
+        // zombie?
+        auto old_pid = server.getPid();
+        if (server.tryWait()) {
+          cerr << "Collected zombie " << server << "(old pid=" << old_pid << ")\n";
+          pids.erase(old_pid);
+          // restart
+          startServer(server);
+        }
+        if (!server.isListening()) {
+          return false;
         }
       }
-      return server.isListening();
+      return true;
+    }};
+    if (!server_is_listening()) {
+      return false;
     }
   }
 
   return true;
 }
 
+bool Cluster::startServer(Server &server) {
+  if (server.start().has_value()) {
+    pids[server.getPid()] = &server;
+    return true;
+  }
+  return false;
+}
+
 void Cluster::wait() {
   siginfo_t inf;
 
@@ -94,4 +108,3 @@ void Cluster::wait() {
     }
   }
 }
-