mirror of
https://github.com/mongodb/mongo.git
synced 2024-12-01 09:32:32 +01:00
rs
This commit is contained in:
parent
aaebac3baa
commit
14a72201cf
@ -251,33 +251,33 @@ namespace mongo {
|
||||
|
||||
DBClientWithCommands() : _logLevel(0) { }
|
||||
|
||||
/** helper function. run a simple command where the command expression is simply
|
||||
{ command : 1 }
|
||||
/** helper function. run a simple command where the command expression is simply
|
||||
{ command : 1 }
|
||||
@param info -- where to put result object. may be null if caller doesn't need that info
|
||||
@param command -- command name
|
||||
@return true if the command returned "ok".
|
||||
*/
|
||||
@return true if the command returned "ok".
|
||||
*/
|
||||
bool simpleCommand(const string &dbname, BSONObj *info, const string &command);
|
||||
|
||||
/** Run a database command. Database commands are represented as BSON objects. Common database
|
||||
commands have prebuilt helper functions -- see below. If a helper is not available you can
|
||||
directly call runCommand.
|
||||
directly call runCommand.
|
||||
|
||||
@param dbname database name. Use "admin" for global administrative commands.
|
||||
@param cmd the command object to execute. For example, { ismaster : 1 }
|
||||
@param info the result object the database returns. Typically has { ok : ..., errmsg : ... } fields
|
||||
set.
|
||||
@param options see enum QueryOptions - normally not needed to run a command
|
||||
@return true if the command returned "ok".
|
||||
@return true if the command returned "ok".
|
||||
*/
|
||||
virtual bool runCommand(const string &dbname, const BSONObj& cmd, BSONObj &info, int options=0);
|
||||
|
||||
/** Authorize access to a particular database.
|
||||
Authentication is separate for each database on the server -- you may authenticate for any
|
||||
number of databases on a single connection.
|
||||
The "admin" database is special and once authenticated provides access to all databases on the
|
||||
server.
|
||||
@param digestPassword if password is plain text, set this to true. otherwise assumed to be pre-digested
|
||||
Authentication is separate for each database on the server -- you may authenticate for any
|
||||
number of databases on a single connection.
|
||||
The "admin" database is special and once authenticated provides access to all databases on the
|
||||
server.
|
||||
@param digestPassword if password is plain text, set this to true. otherwise assumed to be pre-digested
|
||||
@return true if successful
|
||||
*/
|
||||
virtual bool auth(const string &dbname, const string &username, const string &pwd, string& errmsg, bool digestPassword = true);
|
||||
@ -826,5 +826,4 @@ namespace mongo {
|
||||
} // namespace mongo
|
||||
|
||||
#include "dbclientcursor.h"
|
||||
|
||||
#include "undef_macros.h"
|
||||
|
@ -21,32 +21,56 @@
|
||||
|
||||
namespace mongo {
|
||||
|
||||
bool ReplSet::Consensus::aMajoritySeemsToBeUp() const {
|
||||
int ReplSet::Consensus::totalVotes() const {
|
||||
Member *m =rs.head();
|
||||
unsigned vTot = 0, vUp = 0;
|
||||
int vTot = rs._self->config().votes;
|
||||
for( Member *m = rs.head(); m; m=m->next() ) {
|
||||
vTot += m->config().votes;
|
||||
vUp += m->up() ? m->config().votes : 0;
|
||||
}
|
||||
return vUp * 2 > vTot;
|
||||
return vTot;
|
||||
}
|
||||
|
||||
class E : public BackgroundJob {
|
||||
void run() {
|
||||
log() << "not done" << endl;
|
||||
try {
|
||||
ScopedConn c(m->fullName());
|
||||
//c.runCommand(
|
||||
}
|
||||
catch(DBException&) {
|
||||
}
|
||||
bool ReplSet::Consensus::aMajoritySeemsToBeUp() const {
|
||||
Member *m =rs.head();
|
||||
int vUp = rs._self->config().votes;
|
||||
for( Member *m = rs.head(); m; m=m->next() ) {
|
||||
vUp += m->up() ? m->config().votes : 0;
|
||||
}
|
||||
return vUp * 2 > totalVotes();
|
||||
}
|
||||
|
||||
static BSONObj electCmd;
|
||||
|
||||
class E : public BackgroundJob {
|
||||
void run() {
|
||||
ok = 0;
|
||||
log() << "not done" << endl;
|
||||
try {
|
||||
ScopedConn c(m->fullName());
|
||||
if( c->runCommand("admin", electCmd, result) )
|
||||
ok++;
|
||||
}
|
||||
public:
|
||||
ReplSet::Member *m;
|
||||
};
|
||||
typedef shared_ptr<E> eptr;
|
||||
catch(DBException&) {
|
||||
}
|
||||
}
|
||||
public:
|
||||
BSONObj result;
|
||||
int ok;
|
||||
ReplSet::Member *m;
|
||||
};
|
||||
typedef shared_ptr<E> eptr;
|
||||
|
||||
static const int VETO = -10000;
|
||||
|
||||
void ReplSet::Consensus::electSelf() {
|
||||
ReplSet::Member& me = *rs._self;
|
||||
electCmd = BSON(
|
||||
"replSetElect" << 1 <<
|
||||
"set" << rs.getName() <<
|
||||
"who" << me.fullName() <<
|
||||
"whoid" << me._id <<
|
||||
"cfgver" << rs._cfg->version
|
||||
);
|
||||
list<eptr> jobs;
|
||||
list<BackgroundJob*> _jobs;
|
||||
for( Member *m = rs.head(); m; m=m->next() ) if( m->up() ) {
|
||||
@ -55,7 +79,15 @@ namespace mongo {
|
||||
jobs.push_back(eptr(e)); _jobs.push_back(e);
|
||||
e->go();
|
||||
}
|
||||
|
||||
BackgroundJob::wait(_jobs,5);
|
||||
|
||||
int tally = me.config().votes; // me votes yes.
|
||||
for( list<eptr>::iterator i = jobs.begin(); i != jobs.end(); i++ ) {
|
||||
if( (*i)->ok ) {
|
||||
int v = (*i)->result["vote"].Int();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -84,20 +84,22 @@ namespace mongo {
|
||||
string ReplSet::startupStatusMsg;
|
||||
|
||||
void ReplSet::setFrom(ReplSetConfig& c) {
|
||||
assert( c.ok() );
|
||||
assert( _name.empty() || _name == c._id );
|
||||
_name = c._id;
|
||||
_cfg.reset( new ReplSetConfig(c) );
|
||||
assert( _cfg->ok() );
|
||||
assert( _name.empty() || _name == _cfg->_id );
|
||||
_name = _cfg->_id;
|
||||
assert( !_name.empty() );
|
||||
|
||||
assert( _members.head() == 0 );
|
||||
int me=0;
|
||||
for( vector<ReplSetConfig::MemberCfg>::iterator i = c.members.begin(); i != c.members.end(); i++ ) {
|
||||
for( vector<ReplSetConfig::MemberCfg>::iterator i = _cfg->members.begin(); i != _cfg->members.end(); i++ ) {
|
||||
const ReplSetConfig::MemberCfg& m = *i;
|
||||
if( m.h.isSelf() ) {
|
||||
me++;
|
||||
assert( _self == 0 );
|
||||
_self = new Member(m.h, m._id, new ReplSetConfig::MemberCfg(m));
|
||||
_self = new Member(m.h, m._id, &m);
|
||||
} else {
|
||||
Member *mi = new Member(m.h, m._id, new ReplSetConfig::MemberCfg(m));
|
||||
Member *mi = new Member(m.h, m._id, &m);
|
||||
_members.push(mi);
|
||||
}
|
||||
}
|
||||
|
@ -68,6 +68,7 @@ namespace mongo {
|
||||
private:
|
||||
string _name;
|
||||
const vector<HostAndPort> *_seeds;
|
||||
auto_ptr<ReplSetConfig> _cfg;
|
||||
|
||||
/** load our configuration from admin.replset. try seed machines too.
|
||||
throws exception if a problem.
|
||||
@ -79,13 +80,14 @@ namespace mongo {
|
||||
struct Consensus {
|
||||
ReplSet &rs;
|
||||
Consensus(ReplSet *t) : rs(*t) { }
|
||||
int totalVotes() const;
|
||||
bool aMajoritySeemsToBeUp() const;
|
||||
void electSelf();
|
||||
} elect;
|
||||
|
||||
public:
|
||||
struct Member : public List1<Member>::Base {
|
||||
Member(HostAndPort h, int ord, ReplSetConfig::MemberCfg *c) :
|
||||
Member(HostAndPort h, int ord, const ReplSetConfig::MemberCfg *c) :
|
||||
_config(c),
|
||||
_port(h.port()), _host(h.host()), _id(ord) {
|
||||
_dead = false;
|
||||
@ -107,12 +109,13 @@ namespace mongo {
|
||||
void summarizeAsHtml(stringstream& s) const;
|
||||
private:
|
||||
friend class FeedbackThread; // feedbackthread is the primary writer to these objects
|
||||
|
||||
const ReplSetConfig::MemberCfg *_config; /* todo: when this changes??? */
|
||||
bool _dead;
|
||||
public:
|
||||
const int _port;
|
||||
const string _host;
|
||||
const int _id; // ordinal
|
||||
private:
|
||||
double _health;
|
||||
time_t _lastHeartbeat;
|
||||
time_t _upSince;
|
||||
|
Loading…
Reference in New Issue
Block a user