Checks if there exists a better process for each singleton (e.g. DD) compared to the process it is currently on. Note: there is a lot of extra logic here to only recruit the blob manager when gate is open. When adding new singletons, just follow the ratekeeper/data distributor examples.
| 588 | // Note: there is a lot of extra logic here to only recruit the blob manager when gate is open. |
| 589 | // When adding new singletons, just follow the ratekeeper/data distributor examples. |
| 590 | void checkBetterSingletons(ClusterControllerData* self) { |
| 591 | if (!self->masterProcessId.present() || |
| 592 | self->db.serverInfo->get().recoveryState < RecoveryState::ACCEPTING_COMMITS) { |
| 593 | return; |
| 594 | } |
| 595 | |
| 596 | // note: this map doesn't consider pids used by existing singletons |
| 597 | std::map<Optional<Standalone<StringRef>>, int> id_used = self->getUsedIds(); |
| 598 | |
| 599 | // We prefer spreading out other roles more than separating singletons on their own process |
| 600 | // so we artificially amplify the pid count for the processes used by non-singleton roles. |
| 601 | // In other words, we make the processes used for other roles less desirable to be used |
| 602 | // by singletons as well. |
| 603 | for (auto& it : id_used) { |
| 604 | it.second *= PID_USED_AMP_FOR_NON_SINGLETON; |
| 605 | } |
| 606 | |
| 607 | // Try to find a new process for each singleton. |
| 608 | WorkerDetails newRKWorker = findNewProcessForSingleton(self, ProcessClass::Ratekeeper, id_used); |
| 609 | WorkerDetails newDDWorker = findNewProcessForSingleton(self, ProcessClass::DataDistributor, id_used); |
| 610 | |
| 611 | WorkerDetails newBMWorker; |
| 612 | if (self->db.blobGranulesEnabled.get()) { |
| 613 | newBMWorker = findNewProcessForSingleton(self, ProcessClass::BlobManager, id_used); |
| 614 | } |
| 615 | |
| 616 | WorkerDetails newEKPWorker; |
| 617 | if (SERVER_KNOBS->ENABLE_ENCRYPTION) { |
| 618 | newEKPWorker = findNewProcessForSingleton(self, ProcessClass::EncryptKeyProxy, id_used); |
| 619 | } |
| 620 | |
| 621 | // Find best possible fitnesses for each singleton. |
| 622 | auto bestFitnessForRK = findBestFitnessForSingleton(self, newRKWorker, ProcessClass::Ratekeeper); |
| 623 | auto bestFitnessForDD = findBestFitnessForSingleton(self, newDDWorker, ProcessClass::DataDistributor); |
| 624 | |
| 625 | ProcessClass::Fitness bestFitnessForBM; |
| 626 | if (self->db.blobGranulesEnabled.get()) { |
| 627 | bestFitnessForBM = findBestFitnessForSingleton(self, newBMWorker, ProcessClass::BlobManager); |
| 628 | } |
| 629 | |
| 630 | ProcessClass::Fitness bestFitnessForEKP; |
| 631 | if (SERVER_KNOBS->ENABLE_ENCRYPTION) { |
| 632 | bestFitnessForEKP = findBestFitnessForSingleton(self, newEKPWorker, ProcessClass::EncryptKeyProxy); |
| 633 | } |
| 634 | |
| 635 | auto& db = self->db.serverInfo->get(); |
| 636 | auto rkSingleton = RatekeeperSingleton(db.ratekeeper); |
| 637 | auto ddSingleton = DataDistributorSingleton(db.distributor); |
| 638 | BlobManagerSingleton bmSingleton(db.blobManager); |
| 639 | EncryptKeyProxySingleton ekpSingleton(db.encryptKeyProxy); |
| 640 | |
| 641 | // Check if the singletons are healthy. |
| 642 | // side effect: try to rerecruit the singletons to more optimal processes |
| 643 | bool rkHealthy = isHealthySingleton<RatekeeperInterface>( |
| 644 | self, newRKWorker, rkSingleton, bestFitnessForRK, self->recruitingRatekeeperID); |
| 645 | |
| 646 | bool ddHealthy = isHealthySingleton<DataDistributorInterface>( |
| 647 | self, newDDWorker, ddSingleton, bestFitnessForDD, self->recruitingDistributorID); |
no test coverage detected