/* returns: # of seconds to sleep before next pass 0 = no sleep recommended 1 = special sentinel indicating adaptive sleep recommended */ int _replMain(OperationContext* txn, ReplSource::SourceVector& sources, int& nApplied) { { ReplInfo r("replMain load sources"); ScopedTransaction transaction(txn, MODE_X); Lock::GlobalWrite lk(txn->lockState()); ReplSource::loadAll(txn, sources); // only need this param for initial reset _replMainStarted = true; } if (sources.empty()) { /* replication is not configured yet (for --slave) in local.sources. Poll for config it every 20 seconds. */ log() << "no source given, add a master to local.sources to start replication" << endl; return 20; } int sleepAdvice = 1; for (ReplSource::SourceVector::iterator i = sources.begin(); i != sources.end(); i++) { ReplSource* s = i->get(); int res = -1; try { res = s->sync(txn, nApplied); bool moreToSync = s->haveMoreDbsToSync(); if (res < 0) { sleepAdvice = 3; } else if (moreToSync) { sleepAdvice = 0; } else if (s->sleepAdvice()) { sleepAdvice = s->sleepAdvice(); } else sleepAdvice = res; } catch (const SyncException&) { log() << "caught SyncException" << endl; return 10; } catch (AssertionException& e) { if (e.severe()) { log() << "replMain AssertionException " << e.what() << endl; return 60; } else { log() << "repl: AssertionException " << e.what() << endl; } replInfo = "replMain caught AssertionException"; } catch (const DBException& e) { log() << "repl: DBException " << e.what() << endl; replInfo = "replMain caught DBException"; } catch (const std::exception& e) { log() << "repl: std::exception " << e.what() << endl; replInfo = "replMain caught std::exception"; } catch (...) { log() << "unexpected exception during replication. replication will halt" << endl; replAllDead = "caught unexpected exception during replication"; } if (res < 0) s->oplogReader.resetConnection(); } return sleepAdvice; }
static void addSourceToList(ReplSource::SourceVector &v, ReplSource& s, ReplSource::SourceVector &old) { if ( !s.syncedTo.isNull() ) { // Don't reuse old ReplSource if there was a forced resync. for ( ReplSource::SourceVector::iterator i = old.begin(); i != old.end(); ) { if ( s == **i ) { v.push_back(*i); old.erase(i); return; } i++; } } v.push_back( shared_ptr< ReplSource >( new ReplSource( s ) ) ); }