summaryrefslogtreecommitdiff
path: root/src/mongo/shell/bench.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/shell/bench.cpp')
-rw-r--r--src/mongo/shell/bench.cpp1486
1 files changed, 737 insertions, 749 deletions
diff --git a/src/mongo/shell/bench.cpp b/src/mongo/shell/bench.cpp
index 99311f23f62..bd446e49018 100644
--- a/src/mongo/shell/bench.cpp
+++ b/src/mongo/shell/bench.cpp
@@ -54,459 +54,505 @@
// TODO: Maybe extract as library to avoid code duplication?
namespace {
- inline pcrecpp::RE_Options flags2options(const char* flags) {
- pcrecpp::RE_Options options;
- options.set_utf8(true);
- while ( flags && *flags ) {
- if ( *flags == 'i' )
- options.set_caseless(true);
- else if ( *flags == 'm' )
- options.set_multiline(true);
- else if ( *flags == 'x' )
- options.set_extended(true);
- flags++;
- }
- return options;
- }
+inline pcrecpp::RE_Options flags2options(const char* flags) {
+ pcrecpp::RE_Options options;
+ options.set_utf8(true);
+ while (flags && *flags) {
+ if (*flags == 'i')
+ options.set_caseless(true);
+ else if (*flags == 'm')
+ options.set_multiline(true);
+ else if (*flags == 'x')
+ options.set_extended(true);
+ flags++;
+ }
+ return options;
+}
}
namespace mongo {
- using std::unique_ptr;
- using std::cout;
- using std::endl;
- using std::map;
-
- BenchRunEventCounter::BenchRunEventCounter() {
- reset();
- }
-
- BenchRunEventCounter::~BenchRunEventCounter() {}
+using std::unique_ptr;
+using std::cout;
+using std::endl;
+using std::map;
- void BenchRunEventCounter::reset() {
- _numEvents = 0;
- _totalTimeMicros = 0;
- }
-
- void BenchRunEventCounter::updateFrom(const BenchRunEventCounter &other) {
- _numEvents += other._numEvents;
- _totalTimeMicros += other._totalTimeMicros;
- }
-
- BenchRunStats::BenchRunStats() {
- reset();
- }
+BenchRunEventCounter::BenchRunEventCounter() {
+ reset();
+}
- BenchRunStats::~BenchRunStats() {}
+BenchRunEventCounter::~BenchRunEventCounter() {}
- void BenchRunStats::reset() {
- error = false;
- errCount = 0;
- opCount = 0;
+void BenchRunEventCounter::reset() {
+ _numEvents = 0;
+ _totalTimeMicros = 0;
+}
- findOneCounter.reset();
- updateCounter.reset();
- insertCounter.reset();
- deleteCounter.reset();
- queryCounter.reset();
- commandCounter.reset();
- trappedErrors.clear();
- }
+void BenchRunEventCounter::updateFrom(const BenchRunEventCounter& other) {
+ _numEvents += other._numEvents;
+ _totalTimeMicros += other._totalTimeMicros;
+}
- void BenchRunStats::updateFrom(const BenchRunStats &other) {
- if (other.error)
- error = true;
- errCount += other.errCount;
- opCount += other.opCount;
-
- findOneCounter.updateFrom(other.findOneCounter);
- updateCounter.updateFrom(other.updateCounter);
- insertCounter.updateFrom(other.insertCounter);
- deleteCounter.updateFrom(other.deleteCounter);
- queryCounter.updateFrom(other.queryCounter);
- commandCounter.updateFrom(other.commandCounter);
-
- for (size_t i = 0; i < other.trappedErrors.size(); ++i)
- trappedErrors.push_back(other.trappedErrors[i]);
- }
+BenchRunStats::BenchRunStats() {
+ reset();
+}
- BenchRunConfig::BenchRunConfig() {
- initializeToDefaults();
- }
+BenchRunStats::~BenchRunStats() {}
- void BenchRunConfig::initializeToDefaults() {
- host = "localhost";
- db = "test";
- username = "";
- password = "";
+void BenchRunStats::reset() {
+ error = false;
+ errCount = 0;
+ opCount = 0;
- parallel = 1;
- seconds = 1.0;
- hideResults = true;
- handleErrors = false;
- hideErrors = false;
+ findOneCounter.reset();
+ updateCounter.reset();
+ insertCounter.reset();
+ deleteCounter.reset();
+ queryCounter.reset();
+ commandCounter.reset();
+ trappedErrors.clear();
+}
- trapPattern.reset();
- noTrapPattern.reset();
- watchPattern.reset();
- noWatchPattern.reset();
+void BenchRunStats::updateFrom(const BenchRunStats& other) {
+ if (other.error)
+ error = true;
+ errCount += other.errCount;
+ opCount += other.opCount;
+
+ findOneCounter.updateFrom(other.findOneCounter);
+ updateCounter.updateFrom(other.updateCounter);
+ insertCounter.updateFrom(other.insertCounter);
+ deleteCounter.updateFrom(other.deleteCounter);
+ queryCounter.updateFrom(other.queryCounter);
+ commandCounter.updateFrom(other.commandCounter);
+
+ for (size_t i = 0; i < other.trappedErrors.size(); ++i)
+ trappedErrors.push_back(other.trappedErrors[i]);
+}
- ops = BSONObj();
+BenchRunConfig::BenchRunConfig() {
+ initializeToDefaults();
+}
- throwGLE = false;
- breakOnTrap = true;
- randomSeed = 1314159265358979323;
- }
+void BenchRunConfig::initializeToDefaults() {
+ host = "localhost";
+ db = "test";
+ username = "";
+ password = "";
- BenchRunConfig *BenchRunConfig::createFromBson( const BSONObj &args ) {
- BenchRunConfig *config = new BenchRunConfig();
- config->initializeFromBson( args );
- return config;
- }
+ parallel = 1;
+ seconds = 1.0;
+ hideResults = true;
+ handleErrors = false;
+ hideErrors = false;
- void BenchRunConfig::initializeFromBson( const BSONObj &args ) {
- initializeToDefaults();
-
- if ( args["host"].type() == String )
- this->host = args["host"].String();
- if ( args["db"].type() == String )
- this->db = args["db"].String();
- if ( args["username"].type() == String )
- this->username = args["username"].String();
- if ( args["password"].type() == String )
- this->password = args["password"].String();
-
- if ( args["parallel"].isNumber() )
- this->parallel = args["parallel"].numberInt();
- if ( args["randomSeed"].isNumber() )
- this->randomSeed = args["randomSeed"].numberInt();
- if ( args["seconds"].isNumber() )
- this->seconds = args["seconds"].number();
- if ( ! args["hideResults"].eoo() )
- this->hideResults = args["hideResults"].trueValue();
- if ( ! args["handleErrors"].eoo() )
- this->handleErrors = args["handleErrors"].trueValue();
- if ( ! args["hideErrors"].eoo() )
- this->hideErrors = args["hideErrors"].trueValue();
- if ( ! args["throwGLE"].eoo() )
- this->throwGLE = args["throwGLE"].trueValue();
- if ( ! args["breakOnTrap"].eoo() )
- this->breakOnTrap = args["breakOnTrap"].trueValue();
-
- uassert(16164, "loopCommands config not supported", args["loopCommands"].eoo());
-
- if ( ! args["trapPattern"].eoo() ){
- const char* regex = args["trapPattern"].regex();
- const char* flags = args["trapPattern"].regexFlags();
- this->trapPattern = std::shared_ptr< pcrecpp::RE >( new pcrecpp::RE( regex, flags2options( flags ) ) );
- }
+ trapPattern.reset();
+ noTrapPattern.reset();
+ watchPattern.reset();
+ noWatchPattern.reset();
- if ( ! args["noTrapPattern"].eoo() ){
- const char* regex = args["noTrapPattern"].regex();
- const char* flags = args["noTrapPattern"].regexFlags();
- this->noTrapPattern = std::shared_ptr< pcrecpp::RE >( new pcrecpp::RE( regex, flags2options( flags ) ) );
- }
+ ops = BSONObj();
- if ( ! args["watchPattern"].eoo() ){
- const char* regex = args["watchPattern"].regex();
- const char* flags = args["watchPattern"].regexFlags();
- this->watchPattern = std::shared_ptr< pcrecpp::RE >( new pcrecpp::RE( regex, flags2options( flags ) ) );
- }
+ throwGLE = false;
+ breakOnTrap = true;
+ randomSeed = 1314159265358979323;
+}
- if ( ! args["noWatchPattern"].eoo() ){
- const char* regex = args["noWatchPattern"].regex();
- const char* flags = args["noWatchPattern"].regexFlags();
- this->noWatchPattern = std::shared_ptr< pcrecpp::RE >( new pcrecpp::RE( regex, flags2options( flags ) ) );
- }
+BenchRunConfig* BenchRunConfig::createFromBson(const BSONObj& args) {
+ BenchRunConfig* config = new BenchRunConfig();
+ config->initializeFromBson(args);
+ return config;
+}
- this->ops = args["ops"].Obj().getOwned();
- }
+void BenchRunConfig::initializeFromBson(const BSONObj& args) {
+ initializeToDefaults();
+
+ if (args["host"].type() == String)
+ this->host = args["host"].String();
+ if (args["db"].type() == String)
+ this->db = args["db"].String();
+ if (args["username"].type() == String)
+ this->username = args["username"].String();
+ if (args["password"].type() == String)
+ this->password = args["password"].String();
+
+ if (args["parallel"].isNumber())
+ this->parallel = args["parallel"].numberInt();
+ if (args["randomSeed"].isNumber())
+ this->randomSeed = args["randomSeed"].numberInt();
+ if (args["seconds"].isNumber())
+ this->seconds = args["seconds"].number();
+ if (!args["hideResults"].eoo())
+ this->hideResults = args["hideResults"].trueValue();
+ if (!args["handleErrors"].eoo())
+ this->handleErrors = args["handleErrors"].trueValue();
+ if (!args["hideErrors"].eoo())
+ this->hideErrors = args["hideErrors"].trueValue();
+ if (!args["throwGLE"].eoo())
+ this->throwGLE = args["throwGLE"].trueValue();
+ if (!args["breakOnTrap"].eoo())
+ this->breakOnTrap = args["breakOnTrap"].trueValue();
+
+ uassert(16164, "loopCommands config not supported", args["loopCommands"].eoo());
+
+ if (!args["trapPattern"].eoo()) {
+ const char* regex = args["trapPattern"].regex();
+ const char* flags = args["trapPattern"].regexFlags();
+ this->trapPattern =
+ std::shared_ptr<pcrecpp::RE>(new pcrecpp::RE(regex, flags2options(flags)));
+ }
+
+ if (!args["noTrapPattern"].eoo()) {
+ const char* regex = args["noTrapPattern"].regex();
+ const char* flags = args["noTrapPattern"].regexFlags();
+ this->noTrapPattern =
+ std::shared_ptr<pcrecpp::RE>(new pcrecpp::RE(regex, flags2options(flags)));
+ }
+
+ if (!args["watchPattern"].eoo()) {
+ const char* regex = args["watchPattern"].regex();
+ const char* flags = args["watchPattern"].regexFlags();
+ this->watchPattern =
+ std::shared_ptr<pcrecpp::RE>(new pcrecpp::RE(regex, flags2options(flags)));
+ }
+
+ if (!args["noWatchPattern"].eoo()) {
+ const char* regex = args["noWatchPattern"].regex();
+ const char* flags = args["noWatchPattern"].regexFlags();
+ this->noWatchPattern =
+ std::shared_ptr<pcrecpp::RE>(new pcrecpp::RE(regex, flags2options(flags)));
+ }
+
+ this->ops = args["ops"].Obj().getOwned();
+}
- DBClientBase *BenchRunConfig::createConnection() const {
- const ConnectionString connectionString = uassertStatusOK(ConnectionString::parse(host));
+DBClientBase* BenchRunConfig::createConnection() const {
+ const ConnectionString connectionString = uassertStatusOK(ConnectionString::parse(host));
- std::string errorMessage;
- DBClientBase *connection = connectionString.connect(errorMessage);
- uassert( 16158, errorMessage, connection != NULL );
+ std::string errorMessage;
+ DBClientBase* connection = connectionString.connect(errorMessage);
+ uassert(16158, errorMessage, connection != NULL);
- return connection;
- }
+ return connection;
+}
- BenchRunState::BenchRunState( unsigned numWorkers )
- : _mutex(),
- _numUnstartedWorkers( numWorkers ),
- _numActiveWorkers( 0 ),
- _isShuttingDown( 0 ),
- _isCollectingStats( 0 ) {
- }
+BenchRunState::BenchRunState(unsigned numWorkers)
+ : _mutex(),
+ _numUnstartedWorkers(numWorkers),
+ _numActiveWorkers(0),
+ _isShuttingDown(0),
+ _isCollectingStats(0) {}
- BenchRunState::~BenchRunState() {
- wassert(_numActiveWorkers == 0 && _numUnstartedWorkers == 0);
- }
+BenchRunState::~BenchRunState() {
+ wassert(_numActiveWorkers == 0 && _numUnstartedWorkers == 0);
+}
- void BenchRunState::waitForState(State awaitedState) {
- stdx::unique_lock<stdx::mutex> lk(_mutex);
+void BenchRunState::waitForState(State awaitedState) {
+ stdx::unique_lock<stdx::mutex> lk(_mutex);
- switch ( awaitedState ) {
+ switch (awaitedState) {
case BRS_RUNNING:
- while ( _numUnstartedWorkers > 0 ) {
- massert( 16147, "Already finished.", _numUnstartedWorkers + _numActiveWorkers > 0 );
- _stateChangeCondition.wait( lk );
+ while (_numUnstartedWorkers > 0) {
+ massert(16147, "Already finished.", _numUnstartedWorkers + _numActiveWorkers > 0);
+ _stateChangeCondition.wait(lk);
}
break;
case BRS_FINISHED:
- while ( _numUnstartedWorkers + _numActiveWorkers > 0 ) {
- _stateChangeCondition.wait( lk );
+ while (_numUnstartedWorkers + _numActiveWorkers > 0) {
+ _stateChangeCondition.wait(lk);
}
break;
default:
- msgasserted(16152, mongoutils::str::stream() << "Cannot wait for state " << awaitedState);
- }
+ msgasserted(16152,
+ mongoutils::str::stream() << "Cannot wait for state " << awaitedState);
}
+}
- void BenchRunState::tellWorkersToFinish() {
- _isShuttingDown.store( 1 );
- }
+void BenchRunState::tellWorkersToFinish() {
+ _isShuttingDown.store(1);
+}
- void BenchRunState::tellWorkersToCollectStats() {
- _isCollectingStats.store( 1 );
- }
+void BenchRunState::tellWorkersToCollectStats() {
+ _isCollectingStats.store(1);
+}
- void BenchRunState::assertFinished() {
- stdx::lock_guard<stdx::mutex> lk(_mutex);
- verify(0 == _numUnstartedWorkers + _numActiveWorkers);
- }
+void BenchRunState::assertFinished() {
+ stdx::lock_guard<stdx::mutex> lk(_mutex);
+ verify(0 == _numUnstartedWorkers + _numActiveWorkers);
+}
- bool BenchRunState::shouldWorkerFinish() {
- return (_isShuttingDown.loadRelaxed() == 1);
- }
+bool BenchRunState::shouldWorkerFinish() {
+ return (_isShuttingDown.loadRelaxed() == 1);
+}
- bool BenchRunState::shouldWorkerCollectStats() {
- return (_isCollectingStats.loadRelaxed() == 1);
- }
+bool BenchRunState::shouldWorkerCollectStats() {
+ return (_isCollectingStats.loadRelaxed() == 1);
+}
- void BenchRunState::onWorkerStarted() {
- stdx::lock_guard<stdx::mutex> lk(_mutex);
- verify( _numUnstartedWorkers > 0 );
- --_numUnstartedWorkers;
- ++_numActiveWorkers;
- if (_numUnstartedWorkers == 0) {
- _stateChangeCondition.notify_all();
- }
+void BenchRunState::onWorkerStarted() {
+ stdx::lock_guard<stdx::mutex> lk(_mutex);
+ verify(_numUnstartedWorkers > 0);
+ --_numUnstartedWorkers;
+ ++_numActiveWorkers;
+ if (_numUnstartedWorkers == 0) {
+ _stateChangeCondition.notify_all();
}
+}
- void BenchRunState::onWorkerFinished() {
- stdx::lock_guard<stdx::mutex> lk(_mutex);
- verify( _numActiveWorkers > 0 );
- --_numActiveWorkers;
- if (_numActiveWorkers + _numUnstartedWorkers == 0) {
- _stateChangeCondition.notify_all();
- }
+void BenchRunState::onWorkerFinished() {
+ stdx::lock_guard<stdx::mutex> lk(_mutex);
+ verify(_numActiveWorkers > 0);
+ --_numActiveWorkers;
+ if (_numActiveWorkers + _numUnstartedWorkers == 0) {
+ _stateChangeCondition.notify_all();
}
+}
- BSONObj benchStart( const BSONObj& , void* );
- BSONObj benchFinish( const BSONObj& , void* );
+BSONObj benchStart(const BSONObj&, void*);
+BSONObj benchFinish(const BSONObj&, void*);
- static bool _hasSpecial( const BSONObj& obj ) {
- BSONObjIterator i( obj );
- while ( i.more() ) {
- BSONElement e = i.next();
- if ( e.fieldName()[0] == '#' )
- return true;
+static bool _hasSpecial(const BSONObj& obj) {
+ BSONObjIterator i(obj);
+ while (i.more()) {
+ BSONElement e = i.next();
+ if (e.fieldName()[0] == '#')
+ return true;
- if ( ! e.isABSONObj() )
- continue;
+ if (!e.isABSONObj())
+ continue;
- if ( _hasSpecial( e.Obj() ) )
- return true;
- }
- return false;
+ if (_hasSpecial(e.Obj()))
+ return true;
}
+ return false;
+}
- static BSONObj fixQuery( const BSONObj& obj, BsonTemplateEvaluator& btl ) {
- if ( ! _hasSpecial( obj ) )
- return obj;
- BSONObjBuilder b( obj.objsize() + 128 );
+static BSONObj fixQuery(const BSONObj& obj, BsonTemplateEvaluator& btl) {
+ if (!_hasSpecial(obj))
+ return obj;
+ BSONObjBuilder b(obj.objsize() + 128);
- verify(BsonTemplateEvaluator::StatusSuccess == btl.evaluate(obj, b));
- return b.obj();
- }
+ verify(BsonTemplateEvaluator::StatusSuccess == btl.evaluate(obj, b));
+ return b.obj();
+}
- BenchRunWorker::BenchRunWorker(size_t id, const BenchRunConfig *config, BenchRunState *brState,
- int64_t randomSeed)
- : _id(id), _config(config), _brState(brState), _randomSeed(randomSeed) {
- }
+BenchRunWorker::BenchRunWorker(size_t id,
+ const BenchRunConfig* config,
+ BenchRunState* brState,
+ int64_t randomSeed)
+ : _id(id), _config(config), _brState(brState), _randomSeed(randomSeed) {}
- BenchRunWorker::~BenchRunWorker() {}
+BenchRunWorker::~BenchRunWorker() {}
- void BenchRunWorker::start() {
- stdx::thread(stdx::bind(&BenchRunWorker::run, this));
- }
+void BenchRunWorker::start() {
+ stdx::thread(stdx::bind(&BenchRunWorker::run, this));
+}
- bool BenchRunWorker::shouldStop() const {
- return _brState->shouldWorkerFinish();
- }
+bool BenchRunWorker::shouldStop() const {
+ return _brState->shouldWorkerFinish();
+}
- bool BenchRunWorker::shouldCollectStats() const {
- return _brState->shouldWorkerCollectStats();
- }
+bool BenchRunWorker::shouldCollectStats() const {
+ return _brState->shouldWorkerCollectStats();
+}
- void doNothing(const BSONObj&) { }
+void doNothing(const BSONObj&) {}
- void BenchRunWorker::generateLoadOnConnection( DBClientBase* conn ) {
- verify( conn );
- long long count = 0;
- mongo::Timer timer;
+void BenchRunWorker::generateLoadOnConnection(DBClientBase* conn) {
+ verify(conn);
+ long long count = 0;
+ mongo::Timer timer;
- BsonTemplateEvaluator bsonTemplateEvaluator(_randomSeed);
- invariant(bsonTemplateEvaluator.setId(_id) == BsonTemplateEvaluator::StatusSuccess);
+ BsonTemplateEvaluator bsonTemplateEvaluator(_randomSeed);
+ invariant(bsonTemplateEvaluator.setId(_id) == BsonTemplateEvaluator::StatusSuccess);
- if (_config->username != "") {
- string errmsg;
- if (!conn->auth("admin", _config->username, _config->password, errmsg)) {
- uasserted(15931, "Authenticating to connection for _benchThread failed: " + errmsg);
- }
+ if (_config->username != "") {
+ string errmsg;
+ if (!conn->auth("admin", _config->username, _config->password, errmsg)) {
+ uasserted(15931, "Authenticating to connection for _benchThread failed: " + errmsg);
}
+ }
- while ( !shouldStop() ) {
- BSONObjIterator i( _config->ops );
- while ( i.more() ) {
-
- if ( shouldStop() ) break;
- auto& stats = shouldCollectStats() ? _stats : _statsBlackHole;
- BSONElement e = i.next();
-
- string ns = e["ns"].String();
- string op = e["op"].String();
+ while (!shouldStop()) {
+ BSONObjIterator i(_config->ops);
+ while (i.more()) {
+ if (shouldStop())
+ break;
+ auto& stats = shouldCollectStats() ? _stats : _statsBlackHole;
+ BSONElement e = i.next();
- int delay = e["delay"].eoo() ? 0 : e["delay"].Int();
+ string ns = e["ns"].String();
+ string op = e["op"].String();
- // Let's default to writeCmd == false.
- bool useWriteCmd = e["writeCmd"].eoo() ? false :
- e["writeCmd"].Bool();
+ int delay = e["delay"].eoo() ? 0 : e["delay"].Int();
- BSONObj context = e["context"].eoo() ? BSONObj() : e["context"].Obj();
+ // Let's default to writeCmd == false.
+ bool useWriteCmd = e["writeCmd"].eoo() ? false : e["writeCmd"].Bool();
- unique_ptr<Scope> scope;
- ScriptingFunction scopeFunc = 0;
- BSONObj scopeObj;
+ BSONObj context = e["context"].eoo() ? BSONObj() : e["context"].Obj();
- bool check = ! e["check"].eoo();
- if( check ){
- if ( e["check"].type() == CodeWScope || e["check"].type() == Code || e["check"].type() == String ) {
- scope = globalScriptEngine->getPooledScope(NULL, ns, "benchrun");
- verify( scope.get() );
+ unique_ptr<Scope> scope;
+ ScriptingFunction scopeFunc = 0;
+ BSONObj scopeObj;
- if ( e.type() == CodeWScope ) {
- scopeFunc = scope->createFunction( e["check"].codeWScopeCode() );
- scopeObj = BSONObj( e.codeWScopeScopeDataUnsafe() );
- }
- else {
- scopeFunc = scope->createFunction( e["check"].valuestr() );
- }
+ bool check = !e["check"].eoo();
+ if (check) {
+ if (e["check"].type() == CodeWScope || e["check"].type() == Code ||
+ e["check"].type() == String) {
+ scope = globalScriptEngine->getPooledScope(NULL, ns, "benchrun");
+ verify(scope.get());
- scope->init( &scopeObj );
- invariant(scopeFunc);
- }
- else {
- warning() << "Invalid check type detected in benchRun op : " << e << endl;
- check = false;
+ if (e.type() == CodeWScope) {
+ scopeFunc = scope->createFunction(e["check"].codeWScopeCode());
+ scopeObj = BSONObj(e.codeWScopeScopeDataUnsafe());
+ } else {
+ scopeFunc = scope->createFunction(e["check"].valuestr());
}
+
+ scope->init(&scopeObj);
+ invariant(scopeFunc);
+ } else {
+ warning() << "Invalid check type detected in benchRun op : " << e << endl;
+ check = false;
}
+ }
- try {
- if ( op == "nop") {
- // do nothing
+ try {
+ if (op == "nop") {
+ // do nothing
+ } else if (op == "findOne") {
+ BSONObj result;
+ {
+ BenchRunEventTrace _bret(&stats.findOneCounter);
+ result =
+ conn->findOne(ns, fixQuery(e["query"].Obj(), bsonTemplateEvaluator));
}
- else if ( op == "findOne" ) {
-
- BSONObj result;
- {
- BenchRunEventTrace _bret(&stats.findOneCounter);
- result = conn->findOne( ns , fixQuery( e["query"].Obj(),
- bsonTemplateEvaluator ) );
- }
- if( check ){
- int err = scope->invoke( scopeFunc , 0 , &result, 1000 * 60 , false );
- if( err ){
- log() << "Error checking in benchRun thread [findOne]" << causedBy( scope->getError() ) << endl;
+ if (check) {
+ int err = scope->invoke(scopeFunc, 0, &result, 1000 * 60, false);
+ if (err) {
+ log() << "Error checking in benchRun thread [findOne]"
+ << causedBy(scope->getError()) << endl;
- stats.errCount++;
+ stats.errCount++;
- return;
- }
+ return;
}
+ }
- if( ! _config->hideResults || e["showResult"].trueValue() ) log() << "Result from benchRun thread [findOne] : " << result << endl;
-
+ if (!_config->hideResults || e["showResult"].trueValue())
+ log() << "Result from benchRun thread [findOne] : " << result << endl;
+
+ } else if (op == "command") {
+ bool ok;
+ BSONObj result;
+ {
+ BenchRunEventTrace _bret(&stats.commandCounter);
+ ok = conn->runCommand(ns,
+ fixQuery(e["command"].Obj(), bsonTemplateEvaluator),
+ result,
+ e["options"].numberInt());
}
- else if ( op == "command" ) {
-
- bool ok;
- BSONObj result;
- {
- BenchRunEventTrace _bret(&stats.commandCounter);
- ok = conn->runCommand( ns,
- fixQuery( e["command"].Obj(),
- bsonTemplateEvaluator ),
- result,
- e["options"].numberInt());
- }
- if (!ok) {
- stats.errCount++;
- }
- else if( check ){
- int err = scope->invoke( scopeFunc , 0 , &result, 1000 * 60 , false );
- if( err ){
- log() << "Error checking in benchRun thread [command]" << causedBy( scope->getError() ) << endl;
+ if (!ok) {
+ stats.errCount++;
+ } else if (check) {
+ int err = scope->invoke(scopeFunc, 0, &result, 1000 * 60, false);
+ if (err) {
+ log() << "Error checking in benchRun thread [command]"
+ << causedBy(scope->getError()) << endl;
- stats.errCount++;
+ stats.errCount++;
- return;
- }
+ return;
}
+ }
- if( ! _config->hideResults || e["showResult"].trueValue() ) log() << "Result from benchRun thread [command] : " << result << endl;
-
+ if (!_config->hideResults || e["showResult"].trueValue())
+ log() << "Result from benchRun thread [command] : " << result << endl;
+
+ } else if (op == "find" || op == "query") {
+ int limit = e["limit"].eoo() ? 0 : e["limit"].numberInt();
+ int skip = e["skip"].eoo() ? 0 : e["skip"].Int();
+ int options = e["options"].eoo() ? 0 : e["options"].Int();
+ int batchSize = e["batchSize"].eoo() ? 0 : e["batchSize"].Int();
+ BSONObj filter = e["filter"].eoo() ? BSONObj() : e["filter"].Obj();
+ int expected = e["expected"].eoo() ? -1 : e["expected"].Int();
+
+ unique_ptr<DBClientCursor> cursor;
+ int count;
+
+ BSONObj fixedQuery = fixQuery(e["query"].Obj(), bsonTemplateEvaluator);
+
+ // use special query function for exhaust query option
+ if (options & QueryOption_Exhaust) {
+ BenchRunEventTrace _bret(&stats.queryCounter);
+ stdx::function<void(const BSONObj&)> castedDoNothing(doNothing);
+ count = conn->query(castedDoNothing, ns, fixedQuery, &filter, options);
+ } else {
+ BenchRunEventTrace _bret(&stats.queryCounter);
+ cursor =
+ conn->query(ns, fixedQuery, limit, skip, &filter, options, batchSize);
+ count = cursor->itcount();
}
- else if( op == "find" || op == "query" ) {
- int limit = e["limit"].eoo() ? 0 : e["limit"].numberInt();
- int skip = e["skip"].eoo() ? 0 : e["skip"].Int();
- int options = e["options"].eoo() ? 0 : e["options"].Int();
- int batchSize = e["batchSize"].eoo() ? 0 : e["batchSize"].Int();
- BSONObj filter = e["filter"].eoo() ? BSONObj() : e["filter"].Obj();
- int expected = e["expected"].eoo() ? -1 : e["expected"].Int();
+ if (expected >= 0 && count != expected) {
+ cout << "bench query on: " << ns << " expected: " << expected
+ << " got: " << count << endl;
+ verify(false);
+ }
- unique_ptr<DBClientCursor> cursor;
- int count;
+ if (check) {
+ BSONObj thisValue = BSON("count" << count << "context" << context);
+ int err = scope->invoke(scopeFunc, 0, &thisValue, 1000 * 60, false);
+ if (err) {
+ log() << "Error checking in benchRun thread [find]"
+ << causedBy(scope->getError()) << endl;
- BSONObj fixedQuery = fixQuery(e["query"].Obj(), bsonTemplateEvaluator);
+ stats.errCount++;
- // use special query function for exhaust query option
- if (options & QueryOption_Exhaust) {
- BenchRunEventTrace _bret(&stats.queryCounter);
- stdx::function<void (const BSONObj&)> castedDoNothing(doNothing);
- count = conn->query(castedDoNothing, ns, fixedQuery, &filter, options);
- }
- else {
- BenchRunEventTrace _bret(&stats.queryCounter);
- cursor = conn->query(ns, fixedQuery, limit, skip, &filter, options,
- batchSize);
- count = cursor->itcount();
+ return;
}
+ }
- if ( expected >= 0 && count != expected ) {
- cout << "bench query on: " << ns << " expected: " << expected << " got: " << count << endl;
- verify(false);
+ if (!_config->hideResults || e["showResult"].trueValue())
+ log() << "Result from benchRun thread [query] : " << count << endl;
+
+ } else if (op == "update") {
+ bool multi = e["multi"].trueValue();
+ bool upsert = e["upsert"].trueValue();
+ BSONObj queryOrginal = e["query"].eoo() ? BSONObj() : e["query"].Obj();
+ BSONObj updateOriginal = e["update"].Obj();
+ BSONObj result;
+ bool safe = e["safe"].trueValue();
+
+ {
+ BenchRunEventTrace _bret(&stats.updateCounter);
+ BSONObj query = fixQuery(queryOrginal, bsonTemplateEvaluator);
+ BSONObj update = fixQuery(updateOriginal, bsonTemplateEvaluator);
+
+ if (useWriteCmd) {
+ // TODO: Replace after SERVER-11774.
+ BSONObjBuilder builder;
+ builder.append("update", nsToCollectionSubstring(ns));
+ BSONArrayBuilder docBuilder(builder.subarrayStart("updates"));
+ docBuilder.append(BSON("q" << query << "u" << update << "multi" << multi
+ << "upsert" << upsert));
+ docBuilder.done();
+ conn->runCommand(
+ nsToDatabaseSubstring(ns).toString(), builder.done(), result);
+ } else {
+ conn->update(ns, query, update, upsert, multi);
+ if (safe)
+ result = conn->getLastErrorDetailed();
}
+ }
- if( check ){
- BSONObj thisValue = BSON( "count" << count << "context" << context );
- int err = scope->invoke( scopeFunc , 0 , &thisValue, 1000 * 60 , false );
- if( err ){
- log() << "Error checking in benchRun thread [find]" << causedBy( scope->getError() ) << endl;
+ if (safe) {
+ if (check) {
+ int err = scope->invoke(scopeFunc, 0, &result, 1000 * 60, false);
+ if (err) {
+ log() << "Error checking in benchRun thread [update]"
+ << causedBy(scope->getError()) << endl;
stats.errCount++;
@@ -514,464 +560,406 @@ namespace mongo {
}
}
- if( ! _config->hideResults || e["showResult"].trueValue() ) log() << "Result from benchRun thread [query] : " << count << endl;
+ if (!_config->hideResults || e["showResult"].trueValue())
+ log() << "Result from benchRun thread [safe update] : " << result
+ << endl;
+ if (!result["err"].eoo() && result["err"].type() == String &&
+ (_config->throwGLE || e["throwGLE"].trueValue()))
+ throw DBException((string) "From benchRun GLE" +
+ causedBy(result["err"].String()),
+ result["code"].eoo() ? 0 : result["code"].Int());
}
- else if( op == "update" ) {
-
- bool multi = e["multi"].trueValue();
- bool upsert = e["upsert"].trueValue();
- BSONObj queryOrginal = e["query"].eoo() ? BSONObj() : e["query"].Obj();
- BSONObj updateOriginal = e["update"].Obj();
- BSONObj result;
- bool safe = e["safe"].trueValue();
-
- {
- BenchRunEventTrace _bret(&stats.updateCounter);
- BSONObj query = fixQuery(queryOrginal, bsonTemplateEvaluator);
- BSONObj update = fixQuery(updateOriginal, bsonTemplateEvaluator);
-
- if (useWriteCmd) {
- // TODO: Replace after SERVER-11774.
- BSONObjBuilder builder;
- builder.append("update",
- nsToCollectionSubstring(ns));
- BSONArrayBuilder docBuilder(
- builder.subarrayStart("updates"));
- docBuilder.append(BSON("q" << query <<
- "u" << update <<
- "multi" << multi <<
- "upsert" << upsert));
- docBuilder.done();
- conn->runCommand(
- nsToDatabaseSubstring(ns).toString(),
- builder.done(), result);
- }
- else {
- conn->update(ns, query, update,
- upsert , multi);
- if (safe)
- result = conn->getLastErrorDetailed();
- }
+ } else if (op == "insert") {
+ bool safe = e["safe"].trueValue();
+ BSONObj result;
+
+ {
+ BenchRunEventTrace _bret(&stats.insertCounter);
+
+ BSONObj insertDoc = fixQuery(e["doc"].Obj(), bsonTemplateEvaluator);
+
+ if (useWriteCmd) {
+ BSONObjBuilder builder;
+ builder.append("insert", nsToCollectionSubstring(ns));
+ BSONArrayBuilder docBuilder(builder.subarrayStart("documents"));
+ docBuilder.append(insertDoc);
+ docBuilder.done();
+ // TODO: Replace after SERVER-11774.
+ conn->runCommand(
+ nsToDatabaseSubstring(ns).toString(), builder.done(), result);
+ } else {
+ conn->insert(ns, insertDoc);
+ if (safe)
+ result = conn->getLastErrorDetailed();
}
+ }
- if( safe ){
- if( check ){
- int err = scope->invoke( scopeFunc , 0 , &result, 1000 * 60 , false );
- if( err ){
- log() << "Error checking in benchRun thread [update]" << causedBy( scope->getError() ) << endl;
+ if (safe) {
+ if (check) {
+ int err = scope->invoke(scopeFunc, 0, &result, 1000 * 60, false);
+ if (err) {
+ log() << "Error checking in benchRun thread [insert]"
+ << causedBy(scope->getError()) << endl;
- stats.errCount++;
+ stats.errCount++;
- return;
- }
+ return;
}
+ }
- if( ! _config->hideResults || e["showResult"].trueValue() ) log() << "Result from benchRun thread [safe update] : " << result << endl;
+ if (!_config->hideResults || e["showResult"].trueValue())
+ log() << "Result from benchRun thread [safe insert] : " << result
+ << endl;
- if( ! result["err"].eoo() && result["err"].type() == String && ( _config->throwGLE || e["throwGLE"].trueValue() ) )
- throw DBException( (string)"From benchRun GLE" + causedBy( result["err"].String() ),
- result["code"].eoo() ? 0 : result["code"].Int() );
- }
+ if (!result["err"].eoo() && result["err"].type() == String &&
+ (_config->throwGLE || e["throwGLE"].trueValue()))
+ throw DBException((string) "From benchRun GLE" +
+ causedBy(result["err"].String()),
+ result["code"].eoo() ? 0 : result["code"].Int());
}
- else if( op == "insert" ) {
- bool safe = e["safe"].trueValue();
- BSONObj result;
-
- {
- BenchRunEventTrace _bret(&stats.insertCounter);
-
- BSONObj insertDoc = fixQuery(e["doc"].Obj(), bsonTemplateEvaluator);
-
- if (useWriteCmd) {
- BSONObjBuilder builder;
- builder.append("insert", nsToCollectionSubstring(ns));
- BSONArrayBuilder docBuilder(
- builder.subarrayStart("documents"));
- docBuilder.append(insertDoc);
- docBuilder.done();
- // TODO: Replace after SERVER-11774.
- conn->runCommand(
- nsToDatabaseSubstring(ns).toString(),
- builder.done(), result);
- }
- else {
- conn->insert(ns, insertDoc);
- if (safe)
- result = conn->getLastErrorDetailed();
- }
+ } else if (op == "delete" || op == "remove") {
+ bool multi = e["multi"].eoo() ? true : e["multi"].trueValue();
+ BSONObj query = e["query"].eoo() ? BSONObj() : e["query"].Obj();
+ bool safe = e["safe"].trueValue();
+ BSONObj result;
+ {
+ BenchRunEventTrace _bret(&stats.deleteCounter);
+ BSONObj predicate = fixQuery(query, bsonTemplateEvaluator);
+ if (useWriteCmd) {
+ // TODO: Replace after SERVER-11774.
+ BSONObjBuilder builder;
+ builder.append("delete", nsToCollectionSubstring(ns));
+ BSONArrayBuilder docBuilder(builder.subarrayStart("deletes"));
+ int limit = (multi == true) ? 0 : 1;
+ docBuilder.append(BSON("q" << predicate << "limit" << limit));
+ docBuilder.done();
+ conn->runCommand(
+ nsToDatabaseSubstring(ns).toString(), builder.done(), result);
+ } else {
+ conn->remove(ns, predicate, !multi);
+ if (safe)
+ result = conn->getLastErrorDetailed();
}
+ }
- if( safe ){
- if( check ){
- int err = scope->invoke( scopeFunc , 0 , &result, 1000 * 60 , false );
- if( err ){
- log() << "Error checking in benchRun thread [insert]" << causedBy( scope->getError() ) << endl;
-
- stats.errCount++;
-
- return;
- }
- }
+ if (safe) {
+ if (check) {
+ int err = scope->invoke(scopeFunc, 0, &result, 1000 * 60, false);
+ if (err) {
+ log() << "Error checking in benchRun thread [delete]"
+ << causedBy(scope->getError()) << endl;
- if( ! _config->hideResults || e["showResult"].trueValue() ) log() << "Result from benchRun thread [safe insert] : " << result << endl;
+ stats.errCount++;
- if( ! result["err"].eoo() && result["err"].type() == String && ( _config->throwGLE || e["throwGLE"].trueValue() ) )
- throw DBException( (string)"From benchRun GLE" + causedBy( result["err"].String() ),
- result["code"].eoo() ? 0 : result["code"].Int() );
- }
- }
- else if( op == "delete" || op == "remove" ) {
-
- bool multi = e["multi"].eoo() ? true : e["multi"].trueValue();
- BSONObj query = e["query"].eoo() ? BSONObj() : e["query"].Obj();
- bool safe = e["safe"].trueValue();
- BSONObj result;
- {
- BenchRunEventTrace _bret(&stats.deleteCounter);
- BSONObj predicate = fixQuery(query, bsonTemplateEvaluator);
- if (useWriteCmd) {
-
- // TODO: Replace after SERVER-11774.
- BSONObjBuilder builder;
- builder.append("delete",
- nsToCollectionSubstring(ns));
- BSONArrayBuilder docBuilder(
- builder.subarrayStart("deletes"));
- int limit = (multi == true) ? 0 : 1;
- docBuilder.append(
- BSON("q" << predicate <<
- "limit" << limit));
- docBuilder.done();
- conn->runCommand(
- nsToDatabaseSubstring(ns).toString(),
- builder.done(), result);
- }
- else {
- conn->remove(ns, predicate, !multi);
- if (safe)
- result = conn->getLastErrorDetailed();
+ return;
}
}
- if( safe ){
- if( check ){
- int err = scope->invoke( scopeFunc , 0 , &result, 1000 * 60 , false );
- if( err ){
- log() << "Error checking in benchRun thread [delete]" << causedBy( scope->getError() ) << endl;
-
- stats.errCount++;
+ if (!_config->hideResults || e["showResult"].trueValue())
+ log() << "Result from benchRun thread [safe remove] : " << result
+ << endl;
- return;
- }
- }
+ if (!result["err"].eoo() && result["err"].type() == String &&
+ (_config->throwGLE || e["throwGLE"].trueValue()))
+ throw DBException((string) "From benchRun GLE " +
+ causedBy(result["err"].String()),
+ result["code"].eoo() ? 0 : result["code"].Int());
+ }
+ } else if (op == "createIndex") {
+ conn->ensureIndex(ns, e["key"].Obj(), false, "", false);
+ } else if (op == "dropIndex") {
+ conn->dropIndex(ns, e["key"].Obj());
+ } else if (op == "let") {
+ string target = e["target"].eoo() ? string() : e["target"].String();
+ BSONElement value = e["value"].eoo() ? BSONElement() : e["value"];
+ BSONObjBuilder valBuilder;
+ BSONObjBuilder templateBuilder;
+ valBuilder.append(value);
+ bsonTemplateEvaluator.evaluate(valBuilder.done(), templateBuilder);
+ bsonTemplateEvaluator.setVariable(target,
+ templateBuilder.done().firstElement());
+ } else {
+ log() << "don't understand op: " << op << endl;
+ stats.error = true;
+ return;
+ }
+ // Count 1 for total ops. Successfully got through the try phrase
+ stats.opCount++;
+ } catch (DBException& ex) {
+ if (!_config->hideErrors || e["showError"].trueValue()) {
+ bool yesWatch =
+ (_config->watchPattern && _config->watchPattern->FullMatch(ex.what()));
+ bool noWatch =
+ (_config->noWatchPattern && _config->noWatchPattern->FullMatch(ex.what()));
+
+ if ((!_config->watchPattern && _config->noWatchPattern &&
+ !noWatch) || // If we're just ignoring things
+ (!_config->noWatchPattern && _config->watchPattern &&
+ yesWatch) || // If we're just watching things
+ (_config->watchPattern && _config->noWatchPattern && yesWatch && !noWatch))
+ log() << "Error in benchRun thread for op " << e << causedBy(ex) << endl;
+ }
- if( ! _config->hideResults || e["showResult"].trueValue() ) log() << "Result from benchRun thread [safe remove] : " << result << endl;
+ bool yesTrap = (_config->trapPattern && _config->trapPattern->FullMatch(ex.what()));
+ bool noTrap =
+ (_config->noTrapPattern && _config->noTrapPattern->FullMatch(ex.what()));
- if( ! result["err"].eoo() && result["err"].type() == String && ( _config->throwGLE || e["throwGLE"].trueValue() ) )
- throw DBException( (string)"From benchRun GLE " + causedBy( result["err"].String() ),
- result["code"].eoo() ? 0 : result["code"].Int() );
- }
- }
- else if ( op == "createIndex" ) {
- conn->ensureIndex(ns, e["key"].Obj(), false, "", false);
+ if ((!_config->trapPattern && _config->noTrapPattern && !noTrap) ||
+ (!_config->noTrapPattern && _config->trapPattern && yesTrap) ||
+ (_config->trapPattern && _config->noTrapPattern && yesTrap && !noTrap)) {
+ {
+ stats.trappedErrors.push_back(
+ BSON("error" << ex.what() << "op" << e << "count" << count));
}
- else if ( op == "dropIndex" ) {
- conn->dropIndex( ns , e["key"].Obj() );
- }
- else if( op == "let" ) {
- string target = e["target"].eoo() ? string() : e["target"].String();
- BSONElement value = e["value"].eoo() ? BSONElement() : e["value"];
- BSONObjBuilder valBuilder;
- BSONObjBuilder templateBuilder;
- valBuilder.append(value);
- bsonTemplateEvaluator.evaluate(valBuilder.done(), templateBuilder);
- bsonTemplateEvaluator.setVariable(target, templateBuilder.done().firstElement());
- }
- else {
- log() << "don't understand op: " << op << endl;
- stats.error = true;
+ if (_config->breakOnTrap)
return;
- }
- // Count 1 for total ops. Successfully got through the try phrase
- stats.opCount++;
}
- catch( DBException& ex ){
- if( ! _config->hideErrors || e["showError"].trueValue() ){
-
- bool yesWatch = ( _config->watchPattern && _config->watchPattern->FullMatch( ex.what() ) );
- bool noWatch = ( _config->noWatchPattern && _config->noWatchPattern->FullMatch( ex.what() ) );
+ if (!_config->handleErrors && !e["handleError"].trueValue())
+ return;
+
+ stats.errCount++;
+ } catch (...) {
+ if (!_config->hideErrors || e["showError"].trueValue())
+ log() << "Error in benchRun thread caused by unknown error for op " << e
+ << endl;
+ if (!_config->handleErrors && !e["handleError"].trueValue())
+ return;
+
+ stats.errCount++;
+ }
- if( ( ! _config->watchPattern && _config->noWatchPattern && ! noWatch ) || // If we're just ignoring things
- ( ! _config->noWatchPattern && _config->watchPattern && yesWatch ) || // If we're just watching things
- ( _config->watchPattern && _config->noWatchPattern && yesWatch && ! noWatch ) )
- log() << "Error in benchRun thread for op " << e << causedBy( ex ) << endl;
- }
+ if (++count % 100 == 0 && !useWriteCmd) {
+ conn->getLastError();
+ }
- bool yesTrap = ( _config->trapPattern && _config->trapPattern->FullMatch( ex.what() ) );
- bool noTrap = ( _config->noTrapPattern && _config->noTrapPattern->FullMatch( ex.what() ) );
+ if (delay > 0)
+ sleepmillis(delay);
+ }
+ }
- if( ( ! _config->trapPattern && _config->noTrapPattern && ! noTrap ) ||
- ( ! _config->noTrapPattern && _config->trapPattern && yesTrap ) ||
- ( _config->trapPattern && _config->noTrapPattern && yesTrap && ! noTrap ) ){
- {
- stats.trappedErrors.push_back( BSON( "error" << ex.what() << "op" << e << "count" << count ) );
- }
- if( _config->breakOnTrap ) return;
- }
- if( ! _config->handleErrors && ! e["handleError"].trueValue() ) return;
+ conn->getLastError();
+}
- stats.errCount++;
- }
- catch( ... ){
- if( ! _config->hideErrors || e["showError"].trueValue() ) log() << "Error in benchRun thread caused by unknown error for op " << e << endl;
- if( ! _config->handleErrors && ! e["handleError"].trueValue() ) return;
+namespace {
+class BenchRunWorkerStateGuard {
+ MONGO_DISALLOW_COPYING(BenchRunWorkerStateGuard);
- stats.errCount++;
- }
+public:
+ explicit BenchRunWorkerStateGuard(BenchRunState* brState) : _brState(brState) {
+ _brState->onWorkerStarted();
+ }
- if (++count % 100 == 0 && !useWriteCmd) {
- conn->getLastError();
- }
+ ~BenchRunWorkerStateGuard() {
+ _brState->onWorkerFinished();
+ }
- if (delay > 0)
- sleepmillis( delay );
+private:
+ BenchRunState* _brState;
+};
+} // namespace
+void BenchRunWorker::run() {
+ try {
+ std::unique_ptr<DBClientBase> conn(_config->createConnection());
+ if (!_config->username.empty()) {
+ string errmsg;
+ if (!conn->auth("admin", _config->username, _config->password, errmsg)) {
+ uasserted(15932, "Authenticating to connection for benchThread failed: " + errmsg);
}
}
-
- conn->getLastError();
+ BenchRunWorkerStateGuard _workerStateGuard(_brState);
+ generateLoadOnConnection(conn.get());
+ } catch (DBException& e) {
+ error() << "DBException not handled in benchRun thread" << causedBy(e) << endl;
+ } catch (std::exception& e) {
+ error() << "std::exception not handled in benchRun thread" << causedBy(e) << endl;
+ } catch (...) {
+ error() << "Unknown exception not handled in benchRun thread." << endl;
}
+}
- namespace {
- class BenchRunWorkerStateGuard {
- MONGO_DISALLOW_COPYING(BenchRunWorkerStateGuard);
- public:
- explicit BenchRunWorkerStateGuard( BenchRunState *brState ) : _brState( brState ) {
- _brState->onWorkerStarted();
- }
+BenchRunner::BenchRunner(BenchRunConfig* config) : _brState(config->parallel), _config(config) {
+ _oid.init();
+ stdx::lock_guard<stdx::mutex> lk(_staticMutex);
+ _activeRuns[_oid] = this;
+}
- ~BenchRunWorkerStateGuard() {
- _brState->onWorkerFinished();
- }
+BenchRunner::~BenchRunner() {
+ for (size_t i = 0; i < _workers.size(); ++i)
+ delete _workers[i];
+}
- private:
- BenchRunState *_brState;
- };
- } // namespace
-
- void BenchRunWorker::run() {
- try {
- std::unique_ptr<DBClientBase> conn( _config->createConnection() );
- if ( !_config->username.empty() ) {
- string errmsg;
- if (!conn->auth("admin", _config->username, _config->password, errmsg)) {
- uasserted(15932,
- "Authenticating to connection for benchThread failed: " + errmsg);
- }
+void BenchRunner::start() {
+ {
+ std::unique_ptr<DBClientBase> conn(_config->createConnection());
+ // Must authenticate to admin db in order to run serverStatus command
+ if (_config->username != "") {
+ string errmsg;
+ if (!conn->auth("admin", _config->username, _config->password, errmsg)) {
+ uasserted(16704,
+ str::stream()
+ << "User " << _config->username
+ << " could not authenticate to admin db; admin db access is "
+ "required to use benchRun with auth enabled");
}
- BenchRunWorkerStateGuard _workerStateGuard( _brState );
- generateLoadOnConnection( conn.get() );
- }
- catch( DBException& e ){
- error() << "DBException not handled in benchRun thread" << causedBy( e ) << endl;
- }
- catch( std::exception& e ){
- error() << "std::exception not handled in benchRun thread" << causedBy( e ) << endl;
}
- catch( ... ){
- error() << "Unknown exception not handled in benchRun thread." << endl;
+
+ // Start threads
+ for (int64_t i = 0; i < _config->parallel; i++) {
+ // Make a unique random seed for the worker.
+ int64_t seed = _config->randomSeed + i;
+ BenchRunWorker* worker = new BenchRunWorker(i, _config.get(), &_brState, seed);
+ worker->start();
+ _workers.push_back(worker);
}
- }
- BenchRunner::BenchRunner( BenchRunConfig *config )
- : _brState(config->parallel),
- _config(config) {
+ _brState.waitForState(BenchRunState::BRS_RUNNING);
- _oid.init();
- stdx::lock_guard<stdx::mutex> lk(_staticMutex);
- _activeRuns[_oid] = this;
- }
-
- BenchRunner::~BenchRunner() {
- for (size_t i = 0; i < _workers.size(); ++i)
- delete _workers[i];
- }
-
- void BenchRunner::start( ) {
-
- {
- std::unique_ptr<DBClientBase> conn( _config->createConnection() );
- // Must authenticate to admin db in order to run serverStatus command
- if (_config->username != "") {
- string errmsg;
- if (!conn->auth("admin", _config->username, _config->password, errmsg)) {
- uasserted(16704,
- str::stream() << "User " << _config->username
- << " could not authenticate to admin db; admin db access is "
- "required to use benchRun with auth enabled");
- }
- }
-
- // Start threads
- for ( int64_t i = 0; i < _config->parallel; i++ ) {
- // Make a unique random seed for the worker.
- int64_t seed = _config->randomSeed + i;
- BenchRunWorker *worker = new BenchRunWorker(i, _config.get(),
- &_brState, seed);
- worker->start();
- _workers.push_back(worker);
- }
-
- _brState.waitForState(BenchRunState::BRS_RUNNING);
-
- // initial stats
- _brState.tellWorkersToCollectStats();
- _brTimer = new mongo::Timer();
- }
- }
-
- void BenchRunner::stop() {
- _brState.tellWorkersToFinish();
- _brState.waitForState(BenchRunState::BRS_FINISHED);
- _microsElapsed = _brTimer->micros();
- delete _brTimer;
-
- {
- std::unique_ptr<DBClientBase> conn( _config->createConnection() );
- if (_config->username != "") {
- string errmsg;
- // this can only fail if admin access was revoked since start of run
- if (!conn->auth("admin", _config->username, _config->password, errmsg)) {
- uasserted(16705,
- str::stream() << "User " << _config->username
- << " could not authenticate to admin db; admin db access is "
- "still required to use benchRun with auth enabled");
- }
- }
- }
-
- {
- stdx::lock_guard<stdx::mutex> lk(_staticMutex);
- _activeRuns.erase( _oid );
- }
- }
-
- BenchRunner* BenchRunner::createWithConfig( const BSONObj &configArgs ) {
- BenchRunConfig *config = BenchRunConfig::createFromBson( configArgs );
- return new BenchRunner(config);
- }
-
- BenchRunner* BenchRunner::get( OID oid ) {
- stdx::lock_guard<stdx::mutex> lk(_staticMutex);
- return _activeRuns[ oid ];
- }
-
- void BenchRunner::populateStats( BenchRunStats *stats ) {
- _brState.assertFinished();
- stats->reset();
- for ( size_t i = 0; i < _workers.size(); ++i )
- stats->updateFrom( _workers[i]->stats() );
+ // initial stats
+ _brState.tellWorkersToCollectStats();
+ _brTimer = new mongo::Timer();
}
+}
- static void appendAverageMicrosIfAvailable(
- BSONObjBuilder &buf, const std::string &name, const BenchRunEventCounter &counter) {
+void BenchRunner::stop() {
+ _brState.tellWorkersToFinish();
+ _brState.waitForState(BenchRunState::BRS_FINISHED);
+ _microsElapsed = _brTimer->micros();
+ delete _brTimer;
- if (counter.getNumEvents() > 0)
- buf.append(name,
- static_cast<double>(counter.getTotalTimeMicros()) / counter.getNumEvents());
- }
+ {
+ std::unique_ptr<DBClientBase> conn(_config->createConnection());
+ if (_config->username != "") {
+ string errmsg;
+ // this can only fail if admin access was revoked since start of run
+ if (!conn->auth("admin", _config->username, _config->password, errmsg)) {
+ uasserted(16705,
+ str::stream()
+ << "User " << _config->username
+ << " could not authenticate to admin db; admin db access is "
+ "still required to use benchRun with auth enabled");
+ }
+ }
+ }
- BSONObj BenchRunner::finish( BenchRunner* runner ) {
+ {
+ stdx::lock_guard<stdx::mutex> lk(_staticMutex);
+ _activeRuns.erase(_oid);
+ }
+}
- runner->stop();
+BenchRunner* BenchRunner::createWithConfig(const BSONObj& configArgs) {
+ BenchRunConfig* config = BenchRunConfig::createFromBson(configArgs);
+ return new BenchRunner(config);
+}
+
+BenchRunner* BenchRunner::get(OID oid) {
+ stdx::lock_guard<stdx::mutex> lk(_staticMutex);
+ return _activeRuns[oid];
+}
- BenchRunStats stats;
- runner->populateStats(&stats);
+void BenchRunner::populateStats(BenchRunStats* stats) {
+ _brState.assertFinished();
+ stats->reset();
+ for (size_t i = 0; i < _workers.size(); ++i)
+ stats->updateFrom(_workers[i]->stats());
+}
- // vector<BSONOBj> errors = runner->config.errors;
- bool error = stats.error;
+static void appendAverageMicrosIfAvailable(BSONObjBuilder& buf,
+ const std::string& name,
+ const BenchRunEventCounter& counter) {
+ if (counter.getNumEvents() > 0)
+ buf.append(name,
+ static_cast<double>(counter.getTotalTimeMicros()) / counter.getNumEvents());
+}
- if ( error )
- return BSON( "err" << 1 );
+BSONObj BenchRunner::finish(BenchRunner* runner) {
+ runner->stop();
- BSONObjBuilder buf;
- buf.append( "note" , "values per second" );
- buf.append( "errCount", static_cast<long long>(stats.errCount) );
- buf.append( "trapped", "error: not implemented" );
- appendAverageMicrosIfAvailable(buf, "findOneLatencyAverageMicros", stats.findOneCounter);
- appendAverageMicrosIfAvailable(buf, "insertLatencyAverageMicros", stats.insertCounter);
- appendAverageMicrosIfAvailable(buf, "deleteLatencyAverageMicros", stats.deleteCounter);
- appendAverageMicrosIfAvailable(buf, "updateLatencyAverageMicros", stats.updateCounter);
- appendAverageMicrosIfAvailable(buf, "queryLatencyAverageMicros", stats.queryCounter);
- appendAverageMicrosIfAvailable(buf, "commandsLatencyAverageMicros", stats.commandCounter);
+ BenchRunStats stats;
+ runner->populateStats(&stats);
- buf.append("totalOps", static_cast<long long>(stats.opCount));
+ // vector<BSONOBj> errors = runner->config.errors;
+ bool error = stats.error;
- auto appendPerSec = [&buf, runner](StringData name, double total) {
- buf.append(name, total / (runner->_microsElapsed / 1000000.0));
- };
+ if (error)
+ return BSON("err" << 1);
- appendPerSec("totalOps/s", stats.opCount);
- appendPerSec("findOne", stats.findOneCounter.getNumEvents());
- appendPerSec("insert", stats.insertCounter.getNumEvents());
- appendPerSec("delete", stats.deleteCounter.getNumEvents());
- appendPerSec("update", stats.updateCounter.getNumEvents());
- appendPerSec("query", stats.queryCounter.getNumEvents());
- appendPerSec("command", stats.commandCounter.getNumEvents());
+ BSONObjBuilder buf;
+ buf.append("note", "values per second");
+ buf.append("errCount", static_cast<long long>(stats.errCount));
+ buf.append("trapped", "error: not implemented");
+ appendAverageMicrosIfAvailable(buf, "findOneLatencyAverageMicros", stats.findOneCounter);
+ appendAverageMicrosIfAvailable(buf, "insertLatencyAverageMicros", stats.insertCounter);
+ appendAverageMicrosIfAvailable(buf, "deleteLatencyAverageMicros", stats.deleteCounter);
+ appendAverageMicrosIfAvailable(buf, "updateLatencyAverageMicros", stats.updateCounter);
+ appendAverageMicrosIfAvailable(buf, "queryLatencyAverageMicros", stats.queryCounter);
+ appendAverageMicrosIfAvailable(buf, "commandsLatencyAverageMicros", stats.commandCounter);
- BSONObj zoo = buf.obj();
+ buf.append("totalOps", static_cast<long long>(stats.opCount));
- delete runner;
- return zoo;
- }
+ auto appendPerSec = [&buf, runner](StringData name, double total) {
+ buf.append(name, total / (runner->_microsElapsed / 1000000.0));
+ };
- stdx::mutex BenchRunner::_staticMutex;
- map< OID, BenchRunner* > BenchRunner::_activeRuns;
+ appendPerSec("totalOps/s", stats.opCount);
+ appendPerSec("findOne", stats.findOneCounter.getNumEvents());
+ appendPerSec("insert", stats.insertCounter.getNumEvents());
+ appendPerSec("delete", stats.deleteCounter.getNumEvents());
+ appendPerSec("update", stats.updateCounter.getNumEvents());
+ appendPerSec("query", stats.queryCounter.getNumEvents());
+ appendPerSec("command", stats.commandCounter.getNumEvents());
- /**
- * benchRun( { ops : [] , host : XXX , db : XXXX , parallel : 5 , seconds : 5 }
- */
- BSONObj BenchRunner::benchRunSync( const BSONObj& argsFake, void* data ) {
+ BSONObj zoo = buf.obj();
- BSONObj start = benchStart( argsFake, data );
+ delete runner;
+ return zoo;
+}
- OID oid = OID( start.firstElement().String() );
- BenchRunner* runner = BenchRunner::get( oid );
+stdx::mutex BenchRunner::_staticMutex;
+map<OID, BenchRunner*> BenchRunner::_activeRuns;
- sleepmillis( (int)(1000.0 * runner->config().seconds) );
+/**
+ * benchRun( { ops : [] , host : XXX , db : XXXX , parallel : 5 , seconds : 5 }
+ */
+BSONObj BenchRunner::benchRunSync(const BSONObj& argsFake, void* data) {
+ BSONObj start = benchStart(argsFake, data);
- return benchFinish( start, data );
- }
+ OID oid = OID(start.firstElement().String());
+ BenchRunner* runner = BenchRunner::get(oid);
- /**
- * benchRun( { ops : [] , host : XXX , db : XXXX , parallel : 5 , seconds : 5 }
- */
- BSONObj BenchRunner::benchStart( const BSONObj& argsFake, void* data ) {
+ sleepmillis((int)(1000.0 * runner->config().seconds));
- verify( argsFake.firstElement().isABSONObj() );
- BSONObj args = argsFake.firstElement().Obj();
+ return benchFinish(start, data);
+}
- // Get new BenchRunner object
- BenchRunner* runner = BenchRunner::createWithConfig( args );
+/**
+ * benchRun( { ops : [] , host : XXX , db : XXXX , parallel : 5 , seconds : 5 }
+ */
+BSONObj BenchRunner::benchStart(const BSONObj& argsFake, void* data) {
+ verify(argsFake.firstElement().isABSONObj());
+ BSONObj args = argsFake.firstElement().Obj();
- runner->start();
- return BSON( "" << runner->oid().toString() );
- }
+ // Get new BenchRunner object
+ BenchRunner* runner = BenchRunner::createWithConfig(args);
- /**
- * benchRun( { ops : [] , host : XXX , db : XXXX , parallel : 5 , seconds : 5 }
- */
- BSONObj BenchRunner::benchFinish( const BSONObj& argsFake, void* data ) {
+ runner->start();
+ return BSON("" << runner->oid().toString());
+}
- OID oid = OID( argsFake.firstElement().String() );
+/**
+ * benchRun( { ops : [] , host : XXX , db : XXXX , parallel : 5 , seconds : 5 }
+ */
+BSONObj BenchRunner::benchFinish(const BSONObj& argsFake, void* data) {
+ OID oid = OID(argsFake.firstElement().String());
- // Get old BenchRunner object
- BenchRunner* runner = BenchRunner::get( oid );
+ // Get old BenchRunner object
+ BenchRunner* runner = BenchRunner::get(oid);
- BSONObj finalObj = BenchRunner::finish( runner );
+ BSONObj finalObj = BenchRunner::finish(runner);
- return BSON( "" << finalObj );
- }
+ return BSON("" << finalObj);
+}
-} // namespace mongo
+} // namespace mongo