6 Cluster::Cluster(Server serv
, uint16_t cnt
)
11 count
= thread::hardware_concurrency()/2 ?: 4;
21 const vector
<Server
> &Cluster::getServers() const {
25 void Cluster::reset() {
28 for (int i
= 0; i
< count
; ++i
) {
29 cluster
.push_back(proto
);
33 bool Cluster::start() {
36 for (auto &server
: cluster
) {
37 if (!startServer(server
)) {
45 void Cluster::stop() {
46 for (auto &server
: cluster
) {
48 // no cookies for memcached; TERM is just too slow
49 server
.signal(SIGKILL
);
53 bool Cluster::isStopped() {
54 for (auto &server
: cluster
) {
55 if (server
.getPid() && !server
.tryWait()) {
62 bool Cluster::isListening() {
63 for (auto &server
: cluster
) {
64 Retry server_is_listening
{[&] {
65 if (!server
.isListening()) {
67 auto old_pid
= server
.getPid();
68 if (server
.tryWait()) {
69 cerr
<< "Collected zombie " << server
<< "(old pid=" << old_pid
<< ")\n";
74 if (!server
.isListening()) {
80 if (!server_is_listening()) {
88 bool Cluster::startServer(Server
&server
) {
89 if (server
.start().has_value()) {
90 pids
[server
.getPid()] = &server
;
96 void Cluster::wait() {
99 while (!isStopped()) {
100 if (waitid(P_ALL
, 0, &inf
, WEXITED
| WNOWAIT
)) {
101 perror("Cluster::wait waitid()");
105 auto server
= pids
.find(inf
.si_pid
);
106 if (server
!= pids
.end()) {
107 server
->second
->wait();