void doWork() { if ( !theReplSet ) { LOG(2) << "replSet not initialized yet, skipping health poll this round" << rsLog; return; } HeartbeatInfo mem = m; HeartbeatInfo old = mem; bool needsNewStateChecked = false; try { BSONObj info; int theirConfigVersion = -10000; bool ok = _requestHeartbeat(mem, info, theirConfigVersion); // weight new ping with old pings // on the first ping, just use the ping value if (old.ping != 0) { mem.ping = (unsigned int)((old.ping * .8) + (mem.ping * .2)); } if( ok ) { up(info, mem, &needsNewStateChecked); } else if (!info["errmsg"].eoo() && info["errmsg"].str() == "unauthorized") { authIssue(mem); } else { down(mem, info.getStringField("errmsg")); } } catch (const DBException& e) { log() << "replSet health poll task caught a DBException: " << e.what(); down(mem, e.what()); } catch (const std::exception& e) { log() << "replSet health poll task caught an exception: " << e.what(); down(mem, e.what()); } m = mem; theReplSet->mgr->send( boost::bind(&ReplSet::msgUpdateHBInfo, theReplSet, mem) ); static time_t last = 0; time_t now = time(0); bool changed = mem.changed(old); if( changed ) { if( old.hbstate != mem.hbstate ) log() << "replSet member " << h.toString() << " is now in state " << mem.hbstate.toString() << rsLog; } if( needsNewStateChecked || changed || now-last>4 ) { last = now; theReplSet->mgr->send( boost::bind(&Manager::msgCheckNewState, theReplSet->mgr) ); } }
void doWork() { HeartbeatInfo mem = m; HeartbeatInfo old = mem; try { BSONObj info; int theirConfigVersion = -10000; bool ok = requestHeartbeat(theReplSet->name(), h.toString(), info, theReplSet->config().version, theirConfigVersion); mem.lastHeartbeat = time(0); // we set this on any response - we don't get this far if couldn't connect because exception is thrown { be state = info["state"]; if( state.ok() ) mem.hbstate = (MemberState) state.Int(); } if( ok ) { if( mem.upSince == 0 ) { log() << "replSet info " << h.toString() << " is now up" << rsLog; mem.upSince = mem.lastHeartbeat; } mem.health = 1.0; mem.lastHeartbeatMsg = ""; be cfg = info["config"]; if( cfg.ok() ) { // received a new config boost::function<void()> f = boost::bind(&ReplSet::Manager::msgReceivedNewConfig, theReplSet->mgr, cfg.Obj().copy()); theReplSet->mgr->send(f); } } else { down(mem, info.getStringField("errmsg")); } } catch(...) { down(mem, "connect/transport error"); } m = mem; theReplSet->mgr->send( boost::bind(&ReplSet::msgUpdateHBInfo, theReplSet, mem) ); static time_t last = 0; time_t now = time(0); if( mem.changed(old) || now-last>4 ) { last = now; theReplSet->mgr->send( boost::bind(&ReplSet::Manager::msgCheckNewState, theReplSet->mgr) ); } }
void doWork() { if ( !theReplSet ) { log(2) << "theReplSet not initialized yet, skipping health poll this round" << rsLog; return; } HeartbeatInfo mem = m; HeartbeatInfo old = mem; try { BSONObj info; int theirConfigVersion = -10000; Timer timer; bool ok = requestHeartbeat(theReplSet->name(), theReplSet->selfFullName(), h.toString(), info, theReplSet->config().version, theirConfigVersion); mem.ping = (unsigned int)timer.micros(); time_t before = timer.startTime() / 1000000; // we set this on any response - we don't get this far if // couldn't connect because exception is thrown time_t after = mem.lastHeartbeat = before + (mem.ping / 1000000); if ( info["time"].isNumber() ) { long long t = info["time"].numberLong(); if( t > after ) mem.skew = (int) (t - after); else if( t < before ) mem.skew = (int) (t - before); // negative } else { // it won't be there if remote hasn't initialized yet if( info.hasElement("time") ) warning() << "heatbeat.time isn't a number: " << info << endl; mem.skew = INT_MIN; } { be state = info["state"]; if( state.ok() ) mem.hbstate = MemberState(state.Int()); } if( ok ) { if( mem.upSince == 0 ) { log() << "replSet info " << h.toString() << " is up" << rsLog; mem.upSince = mem.lastHeartbeat; } mem.health = 1.0; mem.lastHeartbeatMsg = info["hbmsg"].String(); if( info.hasElement("opTime") ) mem.opTime = info["opTime"].Date(); be cfg = info["config"]; if( cfg.ok() ) { // received a new config boost::function<void()> f = boost::bind(&Manager::msgReceivedNewConfig, theReplSet->mgr, cfg.Obj().copy()); theReplSet->mgr->send(f); } } else { down(mem, info.getStringField("errmsg")); } } catch(DBException& e) { down(mem, e.what()); } catch(...) { down(mem, "something unusual went wrong"); } m = mem; theReplSet->mgr->send( boost::bind(&ReplSet::msgUpdateHBInfo, theReplSet, mem) ); static time_t last = 0; time_t now = time(0); bool changed = mem.changed(old); if( changed ) { if( old.hbstate != mem.hbstate ) log() << "replSet member " << h.toString() << ' ' << mem.hbstate.toString() << rsLog; } if( changed || now-last>4 ) { last = now; theReplSet->mgr->send( boost::bind(&Manager::msgCheckNewState, theReplSet->mgr) ); } }
void doWork() { if ( !theReplSet ) { LOG(2) << "replSet not initialized yet, skipping health poll this round" << rsLog; return; } HeartbeatInfo mem = m; HeartbeatInfo old = mem; try { BSONObj info; int theirConfigVersion = -10000; Timer timer; bool ok = requestHeartbeat(theReplSet->name(), theReplSet->selfFullName(), h.toString(), info, theReplSet->config().version, theirConfigVersion); mem.ping = (unsigned int)timer.millis(); time_t before = timer.startTime() / 1000000; // we set this on any response - we don't get this far if // couldn't connect because exception is thrown time_t after = mem.lastHeartbeat = before + (mem.ping / 1000); // weight new ping with old pings // on the first ping, just use the ping value if (old.ping != 0) { mem.ping = (unsigned int)((old.ping * .8) + (mem.ping * .2)); } if ( info["time"].isNumber() ) { long long t = info["time"].numberLong(); if( t > after ) mem.skew = (int) (t - after); else if( t < before ) mem.skew = (int) (t - before); // negative } else { // it won't be there if remote hasn't initialized yet if( info.hasElement("time") ) warning() << "heatbeat.time isn't a number: " << info << endl; mem.skew = INT_MIN; } { be state = info["state"]; if( state.ok() ) mem.hbstate = MemberState(state.Int()); } if( ok ) { HeartbeatInfo::numPings++; if( mem.upSince == 0 ) { log() << "replSet info member " << h.toString() << " is up" << rsLog; mem.upSince = mem.lastHeartbeat; } mem.health = 1.0; mem.lastHeartbeatMsg = info["hbmsg"].String(); if( info.hasElement("opTime") ) mem.opTime = info["opTime"].Date(); // see if this member is in the electable set if( info["e"].eoo() ) { // for backwards compatibility const Member *member = theReplSet->findById(mem.id()); if (member && member->config().potentiallyHot()) { theReplSet->addToElectable(mem.id()); } else { theReplSet->rmFromElectable(mem.id()); } } // add this server to the electable set if it is within 10 // seconds of the latest optime we know of else if( info["e"].trueValue() && mem.opTime >= theReplSet->lastOpTimeWritten.getSecs() - 10) { unsigned lastOp = theReplSet->lastOtherOpTime().getSecs(); if (lastOp > 0 && mem.opTime >= lastOp - 10) { theReplSet->addToElectable(mem.id()); } } else { theReplSet->rmFromElectable(mem.id()); } be cfg = info["config"]; if( cfg.ok() ) { // received a new config boost::function<void()> f = boost::bind(&Manager::msgReceivedNewConfig, theReplSet->mgr, cfg.Obj().copy()); theReplSet->mgr->send(f); } } else { down(mem, info.getStringField("errmsg")); } } catch(DBException& e) { down(mem, e.what()); } catch(...) { down(mem, "replSet unexpected exception in ReplSetHealthPollTask"); } m = mem; theReplSet->mgr->send( boost::bind(&ReplSet::msgUpdateHBInfo, theReplSet, mem) ); static time_t last = 0; time_t now = time(0); bool changed = mem.changed(old); if( changed ) { if( old.hbstate != mem.hbstate ) log() << "replSet member " << h.toString() << " is now in state " << mem.hbstate.toString() << rsLog; } if( changed || now-last>4 ) { last = now; theReplSet->mgr->send( boost::bind(&Manager::msgCheckNewState, theReplSet->mgr) ); } }
void doWork() { if ( !theReplSet ) { log(2) << "theReplSet not initialized yet, skipping health poll this round" << rsLog; return; } HeartbeatInfo mem = m; HeartbeatInfo old = mem; try { BSONObj info; int theirConfigVersion = -10000; time_t before = time(0); bool ok = requestHeartbeat(theReplSet->name(), theReplSet->selfFullName(), h.toString(), info, theReplSet->config().version, theirConfigVersion); time_t after = mem.lastHeartbeat = time(0); // we set this on any response - we don't get this far if couldn't connect because exception is thrown try { mem.skew = 0; long long t = info["time"].Long(); if( t > after ) mem.skew = (int) (t - after); else if( t < before ) mem.skew = (int) (t - before); // negative } catch(...) { mem.skew = INT_MIN; } { be state = info["state"]; if( state.ok() ) mem.hbstate = MemberState(state.Int()); } if( ok ) { if( mem.upSince == 0 ) { log() << "replSet info " << h.toString() << " is now up" << rsLog; mem.upSince = mem.lastHeartbeat; } mem.health = 1.0; mem.lastHeartbeatMsg = info["hbmsg"].String(); if( info.hasElement("opTime") ) mem.opTime = info["opTime"].Date(); be cfg = info["config"]; if( cfg.ok() ) { // received a new config boost::function<void()> f = boost::bind(&Manager::msgReceivedNewConfig, theReplSet->mgr, cfg.Obj().copy()); theReplSet->mgr->send(f); } } else { down(mem, info.getStringField("errmsg")); } } catch(...) { down(mem, "connect/transport error"); } m = mem; theReplSet->mgr->send( boost::bind(&ReplSet::msgUpdateHBInfo, theReplSet, mem) ); static time_t last = 0; time_t now = time(0); bool changed = mem.changed(old); if( changed ) { if( old.hbstate != mem.hbstate ) log() << "replSet " << h.toString() << ' ' << mem.hbstate.toString() << rsLog; } if( changed || now-last>4 ) { last = now; theReplSet->mgr->send( boost::bind(&Manager::msgCheckNewState, theReplSet->mgr) ); } }