diff options
Diffstat (limited to 'src/mongo/db/repl/elect_cmd_runner.cpp')
-rw-r--r-- | src/mongo/db/repl/elect_cmd_runner.cpp | 203 |
1 files changed, 96 insertions, 107 deletions
diff --git a/src/mongo/db/repl/elect_cmd_runner.cpp b/src/mongo/db/repl/elect_cmd_runner.cpp index c80badf684f..c0d958c428e 100644 --- a/src/mongo/db/repl/elect_cmd_runner.cpp +++ b/src/mongo/db/repl/elect_cmd_runner.cpp @@ -42,119 +42,108 @@ namespace mongo { namespace repl { - ElectCmdRunner::Algorithm::Algorithm( - const ReplicaSetConfig& rsConfig, - int selfIndex, - const std::vector<HostAndPort>& targets, - OID round) - : _actualResponses(0), - _sufficientResponsesReceived(false), - _rsConfig(rsConfig), - _selfIndex(selfIndex), - _targets(targets), - _round(round) { - - // Vote for ourselves, first. - _receivedVotes = _rsConfig.getMemberAt(_selfIndex).getNumVotes(); +ElectCmdRunner::Algorithm::Algorithm(const ReplicaSetConfig& rsConfig, + int selfIndex, + const std::vector<HostAndPort>& targets, + OID round) + : _actualResponses(0), + _sufficientResponsesReceived(false), + _rsConfig(rsConfig), + _selfIndex(selfIndex), + _targets(targets), + _round(round) { + // Vote for ourselves, first. + _receivedVotes = _rsConfig.getMemberAt(_selfIndex).getNumVotes(); +} + +ElectCmdRunner::Algorithm::~Algorithm() {} + +std::vector<RemoteCommandRequest> ElectCmdRunner::Algorithm::getRequests() const { + const MemberConfig& selfConfig = _rsConfig.getMemberAt(_selfIndex); + std::vector<RemoteCommandRequest> requests; + BSONObjBuilder electCmdBuilder; + electCmdBuilder.append("replSetElect", 1); + electCmdBuilder.append("set", _rsConfig.getReplSetName()); + electCmdBuilder.append("who", selfConfig.getHostAndPort().toString()); + electCmdBuilder.append("whoid", selfConfig.getId()); + electCmdBuilder.appendIntOrLL("cfgver", _rsConfig.getConfigVersion()); + electCmdBuilder.append("round", _round); + const BSONObj replSetElectCmd = electCmdBuilder.obj(); + + // Schedule a RemoteCommandRequest for each non-DOWN node + for (std::vector<HostAndPort>::const_iterator it = _targets.begin(); it != _targets.end(); + ++it) { + invariant(*it != selfConfig.getHostAndPort()); + requests.push_back(RemoteCommandRequest( + *it, + "admin", + replSetElectCmd, + Milliseconds(30 * 1000))); // trying to match current Socket timeout } - ElectCmdRunner::Algorithm::~Algorithm() {} - - std::vector<RemoteCommandRequest> - ElectCmdRunner::Algorithm::getRequests() const { - - const MemberConfig& selfConfig = _rsConfig.getMemberAt(_selfIndex); - std::vector<RemoteCommandRequest> requests; - BSONObjBuilder electCmdBuilder; - electCmdBuilder.append("replSetElect", 1); - electCmdBuilder.append("set", _rsConfig.getReplSetName()); - electCmdBuilder.append("who", selfConfig.getHostAndPort().toString()); - electCmdBuilder.append("whoid", selfConfig.getId()); - electCmdBuilder.appendIntOrLL("cfgver", _rsConfig.getConfigVersion()); - electCmdBuilder.append("round", _round); - const BSONObj replSetElectCmd = electCmdBuilder.obj(); - - // Schedule a RemoteCommandRequest for each non-DOWN node - for (std::vector<HostAndPort>::const_iterator it = _targets.begin(); - it != _targets.end(); - ++it) { - - invariant(*it != selfConfig.getHostAndPort()); - requests.push_back(RemoteCommandRequest( - *it, - "admin", - replSetElectCmd, - Milliseconds(30*1000))); // trying to match current Socket timeout - } - - return requests; - } + return requests; +} - bool ElectCmdRunner::Algorithm::hasReceivedSufficientResponses() const { - if (_sufficientResponsesReceived) { - return true; - } - if (_receivedVotes >= _rsConfig.getMajorityVoteCount()) { - return true; - } - if (_receivedVotes < 0) { - return true; - } - if (_actualResponses == _targets.size()) { - return true; - } - return false; +bool ElectCmdRunner::Algorithm::hasReceivedSufficientResponses() const { + if (_sufficientResponsesReceived) { + return true; } - - void ElectCmdRunner::Algorithm::processResponse( - const RemoteCommandRequest& request, - const ResponseStatus& response) { - - ++_actualResponses; - - if (response.isOK()) { - BSONObj res = response.getValue().data; - log() << "received " << res["vote"] << " votes from " << request.target; - LOG(1) << "full elect res: " << res.toString(); - BSONElement vote(res["vote"]); - if (vote.type() != mongo::NumberInt) { - error() << "wrong type for vote argument in replSetElect command: " << - typeName(vote.type()); - _sufficientResponsesReceived = true; - return; - } - - _receivedVotes += vote._numberInt(); - } - else { - warning() << "elect command to " << request.target << " failed: " << - response.getStatus(); - } + if (_receivedVotes >= _rsConfig.getMajorityVoteCount()) { + return true; } - - ElectCmdRunner::ElectCmdRunner() : _isCanceled(false) {} - ElectCmdRunner::~ElectCmdRunner() {} - - StatusWith<ReplicationExecutor::EventHandle> ElectCmdRunner::start( - ReplicationExecutor* executor, - const ReplicaSetConfig& currentConfig, - int selfIndex, - const std::vector<HostAndPort>& targets, - const stdx::function<void ()>& onCompletion) { - - _algorithm.reset(new Algorithm(currentConfig, selfIndex, targets, OID::gen())); - _runner.reset(new ScatterGatherRunner(_algorithm.get())); - return _runner->start(executor, onCompletion); + if (_receivedVotes < 0) { + return true; } - - void ElectCmdRunner::cancel(ReplicationExecutor* executor) { - _isCanceled = true; - _runner->cancel(executor); + if (_actualResponses == _targets.size()) { + return true; } + return false; +} + +void ElectCmdRunner::Algorithm::processResponse(const RemoteCommandRequest& request, + const ResponseStatus& response) { + ++_actualResponses; + + if (response.isOK()) { + BSONObj res = response.getValue().data; + log() << "received " << res["vote"] << " votes from " << request.target; + LOG(1) << "full elect res: " << res.toString(); + BSONElement vote(res["vote"]); + if (vote.type() != mongo::NumberInt) { + error() << "wrong type for vote argument in replSetElect command: " + << typeName(vote.type()); + _sufficientResponsesReceived = true; + return; + } - int ElectCmdRunner::getReceivedVotes() const { - return _algorithm->getReceivedVotes(); + _receivedVotes += vote._numberInt(); + } else { + warning() << "elect command to " << request.target << " failed: " << response.getStatus(); } - -} // namespace repl -} // namespace mongo +} + +ElectCmdRunner::ElectCmdRunner() : _isCanceled(false) {} +ElectCmdRunner::~ElectCmdRunner() {} + +StatusWith<ReplicationExecutor::EventHandle> ElectCmdRunner::start( + ReplicationExecutor* executor, + const ReplicaSetConfig& currentConfig, + int selfIndex, + const std::vector<HostAndPort>& targets, + const stdx::function<void()>& onCompletion) { + _algorithm.reset(new Algorithm(currentConfig, selfIndex, targets, OID::gen())); + _runner.reset(new ScatterGatherRunner(_algorithm.get())); + return _runner->start(executor, onCompletion); +} + +void ElectCmdRunner::cancel(ReplicationExecutor* executor) { + _isCanceled = true; + _runner->cancel(executor); +} + +int ElectCmdRunner::getReceivedVotes() const { + return _algorithm->getReceivedVotes(); +} + +} // namespace repl +} // namespace mongo |