0
0
mirror of https://github.com/mongodb/mongo.git synced 2024-12-01 09:32:32 +01:00
This commit is contained in:
Dwight 2010-05-07 12:37:09 -04:00
parent aaebac3baa
commit 14a72201cf
4 changed files with 73 additions and 37 deletions

View File

@ -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"

View File

@ -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();
}
}
}
}

View File

@ -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);
}
}

View File

@ -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;