mirror of
https://github.com/mongodb/mongo.git
synced 2024-11-28 07:59:02 +01:00
SERVER-18131 Clean up LastError.
Makes LastError a decoration on Client. Removes behavior that was specific to the dbKillCursors wire protocol message into the processing for that message, and out of last error. Simplifies lifetime of LastError. It always exists on Clients, so there's no checking for its existence, and no passing it around through parts of the networking library.
This commit is contained in:
parent
bdbe140e3c
commit
da31be34dc
@ -15,6 +15,7 @@ function aggregateNoOrder(coll, pipeline) {
|
||||
return coll.aggregate(pipeline).toArray();
|
||||
}
|
||||
|
||||
jsTestLog("Creating sharded cluster");
|
||||
var shardedAggTest = new ShardingTest({
|
||||
shards: 2,
|
||||
verbose: 2,
|
||||
@ -23,8 +24,10 @@ var shardedAggTest = new ShardingTest({
|
||||
}
|
||||
);
|
||||
|
||||
jsTestLog("Setting up sharded cluster");
|
||||
shardedAggTest.adminCommand( { enablesharding : "aggShard" } );
|
||||
db = shardedAggTest.getDB( "aggShard" );
|
||||
assert.commandWorked(db.adminCommand({setParameter: 1, logComponentVerbosity: { network: 0 }}));
|
||||
|
||||
/* make sure its cleaned up */
|
||||
db.ts1.drop();
|
||||
@ -69,6 +72,7 @@ var strings = [
|
||||
"twenty"
|
||||
];
|
||||
|
||||
jsTestLog("Bulk inserting data");
|
||||
var nItems = 200000;
|
||||
var bulk = db.ts1.initializeUnorderedBulkOp();
|
||||
for(i = 1; i <= nItems; ++i) {
|
||||
@ -89,7 +93,7 @@ for ( var i = 0; i < shards.length; i++ ) {
|
||||
printjson(shardConn.getDB( "admin" ).runCommand({ setParameter : 1, traceExceptions : true }));
|
||||
}
|
||||
|
||||
// a project and group in shards, result combined in mongos
|
||||
jsTestLog('a project and group in shards, result combined in mongos');
|
||||
var a1 = aggregateNoOrder(db.ts1, [
|
||||
{ $project: {
|
||||
cMod10: {$mod:["$counter", 10]},
|
||||
@ -111,7 +115,7 @@ for(i = 0 ; i < 10; ++i) {
|
||||
'agg sharded test numberSet length failed');
|
||||
}
|
||||
|
||||
// an initial group starts the group in the shards, and combines them in mongos
|
||||
jsTestLog('an initial group starts the group in the shards, and combines them in mongos');
|
||||
var a2 = aggregateOrdered(db.ts1 , [
|
||||
{ $group: {
|
||||
_id: "all",
|
||||
@ -119,11 +123,11 @@ var a2 = aggregateOrdered(db.ts1 , [
|
||||
}}
|
||||
]);
|
||||
|
||||
// sum of an arithmetic progression S(n) = (n/2)(a(1) + a(n));
|
||||
jsTestLog('sum of an arithmetic progression S(n) = (n/2)(a(1) + a(n));');
|
||||
assert.eq(a2[0].total, (nItems/2)*(1 + nItems),
|
||||
'agg sharded test counter sum failed');
|
||||
|
||||
// an initial group starts the group in the shards, and combines them in mongos
|
||||
jsTestLog('an initial group starts the group in the shards, and combines them in mongos');
|
||||
var a3 = aggregateOrdered(db.ts1, [
|
||||
{ $group: {
|
||||
_id: "$number",
|
||||
@ -137,7 +141,7 @@ for(i = 0 ; i < strings.length; ++i) {
|
||||
'agg sharded test sum numbers failed');
|
||||
}
|
||||
|
||||
// a match takes place in the shards; just returning the results from mongos
|
||||
jsTestLog('a match takes place in the shards; just returning the results from mongos');
|
||||
var a4 = aggregateNoOrder(db.ts1, [
|
||||
{ $match: {$or:[{counter:55}, {counter:1111},
|
||||
{counter: 2222}, {counter: 33333},
|
||||
@ -155,6 +159,7 @@ for(i = 0; i < 6; ++i) {
|
||||
}
|
||||
|
||||
function testSkipLimit(ops, expectedCount) {
|
||||
jsTestLog('testSkipLimit(' + tojson(ops) + ', ' + expectedCount + ')');
|
||||
if (expectedCount > 10) {
|
||||
// make shard -> mongos intermediate results less than 16MB
|
||||
ops.unshift({$project: {_id:1}})
|
||||
@ -177,6 +182,7 @@ testSkipLimit([{$limit:10}, {$skip:5}, {$skip: 3}], 10 - 3 - 5);
|
||||
|
||||
// test sort + limit (using random to pull from both shards)
|
||||
function testSortLimit(limit, direction) {
|
||||
jsTestLog('testSortLimit(' + limit + ', ' + direction + ')');
|
||||
shardedAggTest.stopBalancer(); // TODO: remove after fixing SERVER-9622
|
||||
var from_cursor = db.ts1.find({},{random:1, _id:0})
|
||||
.sort({random: direction})
|
||||
@ -196,7 +202,7 @@ testSortLimit(10, -1);
|
||||
testSortLimit(100, 1);
|
||||
testSortLimit(100, -1);
|
||||
|
||||
// test $out by copying source collection verbatim to output
|
||||
jsTestLog('test $out by copying source collection verbatim to output');
|
||||
var outCollection = db.ts1_out;
|
||||
var res = aggregateOrdered(db.ts1, [{$out: outCollection.getName()}]);
|
||||
shardedAggTest.stopBalancer(); // TODO: remove after fixing SERVER-9622
|
||||
@ -215,7 +221,8 @@ result = aggregateOrdered(db.literal,
|
||||
|
||||
assert.eq([{cost:'$.99'}], result);
|
||||
|
||||
// Do a basic sharded explain. This just makes sure that it doesn't error and has the right fields.
|
||||
jsTestLog("Do a basic sharded explain. This just makes sure that it doesn't error and has " +
|
||||
"the right fields.");
|
||||
var res = db.ts1.aggregate([{$project: {a: 1}}], {explain:true});
|
||||
assert.commandWorked(res);
|
||||
printjson(res);
|
||||
@ -231,8 +238,10 @@ for (var shardName in res.shards) {
|
||||
// Call sub-tests designed to work sharded and unsharded.
|
||||
// They check for this variable to know to shard their collections.
|
||||
RUNNING_IN_SHARDED_AGG_TEST = true; // global
|
||||
jsTestLog('running jstests/aggregation/bugs/server9444.js');
|
||||
load("jstests/aggregation/bugs/server9444.js"); // external sort
|
||||
jsTestLog('running jstests/aggregation/bugs/server11675.js');
|
||||
load("jstests/aggregation/bugs/server11675.js"); // text support
|
||||
|
||||
// shut everything down
|
||||
jsTestLog('shut everything down');
|
||||
shardedAggTest.stop();
|
||||
|
@ -156,8 +156,9 @@ env.Library(
|
||||
env.Library('lasterror', [
|
||||
"db/lasterror.cpp",
|
||||
],
|
||||
LIBDEPS=['util/net/network',
|
||||
'util/foundation',
|
||||
LIBDEPS=[
|
||||
'service_context',
|
||||
'util/foundation',
|
||||
])
|
||||
|
||||
def getSysInfo():
|
||||
@ -508,8 +509,9 @@ env.Library(
|
||||
'db/service_context_noop.cpp',
|
||||
],
|
||||
LIBDEPS=[
|
||||
'lasterror', # TODO(schwerin): REMOVE!
|
||||
'util/concurrency/spin_lock',
|
||||
'util/decorable',
|
||||
'util/net/hostandport',
|
||||
])
|
||||
|
||||
# Memory-mapped files support. Used by mongod and some tools.
|
||||
|
@ -103,9 +103,7 @@ namespace mongo {
|
||||
virtual void connected(AbstractMessagingPort* p) {
|
||||
}
|
||||
|
||||
virtual void process(Message& m,
|
||||
AbstractMessagingPort* port,
|
||||
LastError * le) {
|
||||
virtual void process(Message& m, AbstractMessagingPort* por) {
|
||||
boost::this_thread::interruption_point();
|
||||
}
|
||||
};
|
||||
|
@ -83,7 +83,6 @@ namespace mongo {
|
||||
}
|
||||
|
||||
setThreadName(fullDesc.c_str());
|
||||
mongo::lastError.initThread();
|
||||
|
||||
// Create the client obj, attach to thread
|
||||
*currentClient.get() = service->makeClient(fullDesc, mp);
|
||||
|
@ -40,7 +40,6 @@
|
||||
#include <boost/thread/thread.hpp>
|
||||
|
||||
#include "mongo/db/client_basic.h"
|
||||
#include "mongo/db/lasterror.h"
|
||||
#include "mongo/db/namespace_string.h"
|
||||
#include "mongo/db/operation_context.h"
|
||||
#include "mongo/db/service_context.h"
|
||||
|
@ -43,6 +43,7 @@
|
||||
#include "mongo/db/concurrency/write_conflict_exception.h"
|
||||
#include "mongo/db/db_raii.h"
|
||||
#include "mongo/db/exec/working_set_common.h"
|
||||
#include "mongo/db/lasterror.h"
|
||||
#include "mongo/db/namespace_string.h"
|
||||
#include "mongo/db/operation_context.h"
|
||||
#include "mongo/db/ops/delete_request.h"
|
||||
|
@ -72,9 +72,7 @@ namespace mongo {
|
||||
int,
|
||||
string& errmsg,
|
||||
BSONObjBuilder& result) {
|
||||
LastError *le = lastError.get();
|
||||
verify( le );
|
||||
le->reset();
|
||||
LastError::get(txn->getClient()).reset();
|
||||
return true;
|
||||
}
|
||||
} cmdResetError;
|
||||
@ -88,7 +86,7 @@ namespace mongo {
|
||||
const BSONObj& cmdObj,
|
||||
std::vector<Privilege>* out) {} // No auth required
|
||||
virtual void help( stringstream& help ) const {
|
||||
lastError.disableForCommand(); // SERVER-11492
|
||||
LastError::get(cc()).disable(); // SERVER-11492
|
||||
help << "return error status of the last operation on this connection\n"
|
||||
<< "options:\n"
|
||||
<< " { fsync:true } - fsync before returning, or wait for journal commit if running with --journal\n"
|
||||
@ -128,7 +126,8 @@ namespace mongo {
|
||||
// err is null.
|
||||
//
|
||||
|
||||
LastError *le = lastError.disableForCommand();
|
||||
LastError *le = &LastError::get(txn->getClient());
|
||||
le->disable();
|
||||
|
||||
// Always append lastOp and connectionId
|
||||
Client& c = *txn->getClient();
|
||||
@ -173,7 +172,7 @@ namespace mongo {
|
||||
|
||||
// Errors aren't reported when wOpTime is used
|
||||
if ( !lastOpTimePresent ) {
|
||||
if ( le->nPrev != 1 ) {
|
||||
if ( le->getNPrev() != 1 ) {
|
||||
errorOccurred = LastError::noError.appendSelf( result, false );
|
||||
}
|
||||
else {
|
||||
@ -284,12 +283,13 @@ namespace mongo {
|
||||
int,
|
||||
string& errmsg,
|
||||
BSONObjBuilder& result) {
|
||||
LastError *le = lastError.disableForCommand();
|
||||
le->appendSelf( result );
|
||||
if ( le->valid )
|
||||
result.append( "nPrev", le->nPrev );
|
||||
LastError *le = &LastError::get(txn->getClient());
|
||||
le->disable();
|
||||
le->appendSelf(result, true);
|
||||
if (le->isValid())
|
||||
result.append("nPrev", le->getNPrev());
|
||||
else
|
||||
result.append( "nPrev", -1 );
|
||||
result.append("nPrev", -1);
|
||||
return true;
|
||||
}
|
||||
} cmdGetPrevError;
|
||||
|
@ -550,8 +550,10 @@ namespace mongo {
|
||||
|
||||
if ( currWrite.getOpType() == BatchedCommandRequest::BatchType_Insert ) {
|
||||
_stats->numInserted += stats.n;
|
||||
_le->nObjects = stats.n;
|
||||
currentOp->debug().ninserted += stats.n;
|
||||
if (!error) {
|
||||
_le->recordInsert(stats.n);
|
||||
}
|
||||
}
|
||||
else if ( currWrite.getOpType() == BatchedCommandRequest::BatchType_Update ) {
|
||||
if ( stats.upsertedID.isEmpty() ) {
|
||||
@ -562,7 +564,7 @@ namespace mongo {
|
||||
++_stats->numUpserted;
|
||||
}
|
||||
|
||||
if ( !error ) {
|
||||
if (!error) {
|
||||
_le->recordUpdate( stats.upsertedID.isEmpty() && stats.n > 0,
|
||||
stats.n,
|
||||
stats.upsertedID );
|
||||
@ -577,8 +579,8 @@ namespace mongo {
|
||||
currentOp->debug().ndeleted += stats.n;
|
||||
}
|
||||
|
||||
if (error && !_le->disabled) {
|
||||
_le->raiseError(error->getErrCode(), error->getErrMessage().c_str());
|
||||
if (error) {
|
||||
_le->setLastError(error->getErrCode(), error->getErrMessage().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -44,12 +44,11 @@ namespace mongo {
|
||||
|
||||
class BSONObjBuilder;
|
||||
class CurOp;
|
||||
class LastError;
|
||||
class OpCounters;
|
||||
class OperationContext;
|
||||
struct LastError;
|
||||
|
||||
struct WriteOpStats;
|
||||
class WriteBatchStats;
|
||||
struct WriteOpStats;
|
||||
|
||||
/**
|
||||
* An instance of WriteBatchExecutor is an object capable of issuing a write batch.
|
||||
|
@ -104,7 +104,7 @@ namespace mongo {
|
||||
|
||||
// TODO: Remove this when we standardize GLE reporting from commands
|
||||
if ( !status.isOK() ) {
|
||||
setLastError( status.code(), status.reason().c_str() );
|
||||
LastError::get(client).setLastError(status.code(), status.reason());
|
||||
}
|
||||
|
||||
return status;
|
||||
@ -145,7 +145,7 @@ namespace mongo {
|
||||
|
||||
WriteBatchExecutor writeBatchExecutor(txn,
|
||||
&globalOpCounters,
|
||||
lastError.get());
|
||||
&LastError::get(txn->getClient()));
|
||||
|
||||
writeBatchExecutor.executeBatch( request, &response );
|
||||
|
||||
|
@ -70,7 +70,6 @@
|
||||
#include "mongo/db/instance.h"
|
||||
#include "mongo/db/introspect.h"
|
||||
#include "mongo/db/json.h"
|
||||
#include "mongo/db/lasterror.h"
|
||||
#include "mongo/db/log_process_details.h"
|
||||
#include "mongo/db/mongod_options.h"
|
||||
#include "mongo/db/op_observer.h"
|
||||
@ -157,7 +156,7 @@ namespace mongo {
|
||||
Client::initThread("conn", p);
|
||||
}
|
||||
|
||||
virtual void process( Message& m , AbstractMessagingPort* port , LastError * le) {
|
||||
virtual void process(Message& m , AbstractMessagingPort* port) {
|
||||
OperationContextImpl txn;
|
||||
while ( true ) {
|
||||
if ( inShutdown() ) {
|
||||
@ -165,8 +164,6 @@ namespace mongo {
|
||||
break;
|
||||
}
|
||||
|
||||
lastError.startRequest( m , le );
|
||||
|
||||
DbResponse dbresponse;
|
||||
assembleResponse(&txn, m, dbresponse, port->remote());
|
||||
|
||||
|
@ -330,7 +330,7 @@ namespace mongo {
|
||||
int,
|
||||
string& errmsg,
|
||||
BSONObjBuilder& result) {
|
||||
setLastError(10038, "forced error");
|
||||
LastError::get(cc()).setLastError(10038, "forced error");
|
||||
return false;
|
||||
}
|
||||
} cmdForceError;
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "mongo/db/client.h"
|
||||
#include "mongo/db/commands.h"
|
||||
#include "mongo/db/instance.h"
|
||||
#include "mongo/db/lasterror.h"
|
||||
#include "mongo/db/operation_context.h"
|
||||
#include "mongo/util/log.h"
|
||||
|
||||
@ -122,9 +123,7 @@ namespace mongo {
|
||||
bool assertOk,
|
||||
string* actualServer) {
|
||||
DirectClientScope directClientScope(_txn);
|
||||
if (lastError._get()) {
|
||||
lastError.startRequest(toSend, lastError._get());
|
||||
}
|
||||
LastError::get(_txn->getClient()).startRequest();
|
||||
|
||||
DbResponse dbResponse;
|
||||
assembleResponse(_txn, toSend, dbResponse, dummyHost);
|
||||
@ -139,9 +138,7 @@ namespace mongo {
|
||||
|
||||
void DBDirectClient::say(Message& toSend, bool isRetry, string* actualServer) {
|
||||
DirectClientScope directClientScope(_txn);
|
||||
if (lastError._get()) {
|
||||
lastError.startRequest(toSend, lastError._get());
|
||||
}
|
||||
LastError::get(_txn->getClient()).startRequest();
|
||||
|
||||
DbResponse dbResponse;
|
||||
assembleResponse(_txn, toSend, dbResponse, dummyHost);
|
||||
|
@ -391,6 +391,7 @@ namespace {
|
||||
|
||||
Client& c = *txn->getClient();
|
||||
if (!c.isInDirectClient()) {
|
||||
LastError::get(c).startRequest();
|
||||
AuthorizationSession::get(c)->startRequest(txn);
|
||||
|
||||
// We should not be holding any locks at this point
|
||||
@ -558,14 +559,14 @@ namespace {
|
||||
}
|
||||
}
|
||||
catch (const UserException& ue) {
|
||||
setLastError(ue.getCode(), ue.getInfo().msg.c_str());
|
||||
LastError::get(c).setLastError(ue.getCode(), ue.getInfo().msg);
|
||||
MONGO_LOG_COMPONENT(3, responseComponent)
|
||||
<< " Caught Assertion in " << opToString(op) << ", continuing "
|
||||
<< ue.toString() << endl;
|
||||
debug.exceptionInfo = ue.getInfo();
|
||||
}
|
||||
catch (const AssertionException& e) {
|
||||
setLastError(e.getCode(), e.getInfo().msg.c_str());
|
||||
LastError::get(c).setLastError(e.getCode(), e.getInfo().msg);
|
||||
MONGO_LOG_COMPONENT(3, responseComponent)
|
||||
<< " Caught Assertion in " << opToString(op) << ", continuing "
|
||||
<< e.toString() << endl;
|
||||
@ -606,6 +607,7 @@ namespace {
|
||||
}
|
||||
|
||||
void receivedKillCursors(OperationContext* txn, Message& m) {
|
||||
LastError::get(txn->getClient()).disable();
|
||||
DbMessage dbmessage(m);
|
||||
int n = dbmessage.pullInt();
|
||||
|
||||
@ -702,7 +704,8 @@ namespace {
|
||||
UpdateResult res = UpdateStage::makeUpdateResult(exec.get(), &op.debug());
|
||||
|
||||
// for getlasterror
|
||||
lastError.getSafe()->recordUpdate( res.existing , res.numMatched , res.upserted );
|
||||
LastError::get(txn->getClient()).recordUpdate(
|
||||
res.existing, res.numMatched, res.upserted);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
@ -755,7 +758,8 @@ namespace {
|
||||
uassertStatusOK(exec->executePlan());
|
||||
UpdateResult res = UpdateStage::makeUpdateResult(exec.get(), &op.debug());
|
||||
|
||||
lastError.getSafe()->recordUpdate( res.existing , res.numMatched , res.upserted );
|
||||
LastError::get(txn->getClient()).recordUpdate(
|
||||
res.existing, res.numMatched, res.upserted);
|
||||
} MONGO_WRITE_CONFLICT_RETRY_LOOP_END(txn, "update", nsString.ns());
|
||||
}
|
||||
|
||||
@ -813,7 +817,7 @@ namespace {
|
||||
// Run the plan and get the number of docs deleted.
|
||||
uassertStatusOK(exec->executePlan());
|
||||
long long n = DeleteStage::getNumDeleted(exec.get());
|
||||
lastError.getSafe()->recordDelete(n);
|
||||
LastError::get(txn->getClient()).recordDelete(n);
|
||||
op.debug().ndeleted = n;
|
||||
|
||||
break;
|
||||
@ -1003,7 +1007,7 @@ namespace {
|
||||
globalOpCounters.incInsertInWriteLock(i);
|
||||
throw;
|
||||
}
|
||||
setLastError(ex.getCode(), ex.getInfo().msg.c_str());
|
||||
LastError::get(txn->getClient()).setLastError(ex.getCode(), ex.getInfo().msg);
|
||||
// otherwise ignore and keep going
|
||||
}
|
||||
}
|
||||
@ -1057,7 +1061,7 @@ namespace {
|
||||
convertSystemIndexInsertsToCommands(d, &allCmdsBuilder);
|
||||
}
|
||||
catch (const DBException& ex) {
|
||||
setLastError(ex.getCode(), ex.getInfo().msg.c_str());
|
||||
LastError::get(txn->getClient()).setLastError(ex.getCode(), ex.getInfo().msg);
|
||||
curOp.debug().exceptionInfo = ex.getInfo();
|
||||
return;
|
||||
}
|
||||
@ -1079,7 +1083,7 @@ namespace {
|
||||
uassertStatusOK(Command::getStatusFromCommandResult(resultBuilder.done()));
|
||||
}
|
||||
catch (const DBException& ex) {
|
||||
setLastError(ex.getCode(), ex.getInfo().msg.c_str());
|
||||
LastError::get(txn->getClient()).setLastError(ex.getCode(), ex.getInfo().msg);
|
||||
curOp.debug().exceptionInfo = ex.getInfo();
|
||||
if (!keepGoing) {
|
||||
return;
|
||||
|
@ -27,139 +27,91 @@
|
||||
* then also delete it in the license file.
|
||||
*/
|
||||
|
||||
#define MONGO_LOG_DEFAULT_COMPONENT ::mongo::logger::LogComponent::kDefault
|
||||
|
||||
#include "mongo/platform/basic.h"
|
||||
|
||||
#include "mongo/db/lasterror.h"
|
||||
|
||||
#include "mongo/db/jsobj.h"
|
||||
#include "mongo/util/debug_util.h"
|
||||
#include "mongo/util/log.h"
|
||||
#include "mongo/util/net/message.h"
|
||||
#include "mongo/util/assert_util.h"
|
||||
|
||||
namespace mongo {
|
||||
|
||||
using std::endl;
|
||||
|
||||
LastError LastError::noError;
|
||||
LastErrorHolder lastError;
|
||||
|
||||
bool isShell = false;
|
||||
void setLastError(int code , const char *msg) {
|
||||
LastError *le = lastError.get();
|
||||
if ( le == 0 ) {
|
||||
/* might be intentional (non-user thread) */
|
||||
DEV {
|
||||
static unsigned n;
|
||||
if( ++n < 4 && !isShell ) log() << "dev: lastError==0 won't report:" << msg << endl;
|
||||
}
|
||||
}
|
||||
else if ( le->disabled ) {
|
||||
log() << "lastError disabled, can't report: " << code << ":" << msg << endl;
|
||||
}
|
||||
else {
|
||||
le->raiseError(code, msg);
|
||||
}
|
||||
const Client::Decoration<LastError> LastError::get = Client::declareDecoration<LastError>();
|
||||
|
||||
void LastError::reset(bool valid) {
|
||||
*this = LastError();
|
||||
_valid = valid;
|
||||
}
|
||||
|
||||
bool LastError::appendSelf( BSONObjBuilder &b , bool blankErr ) {
|
||||
void LastError::setLastError(int code, std::string msg) {
|
||||
if (_disabled) {
|
||||
return;
|
||||
}
|
||||
reset(true);
|
||||
_code = code;
|
||||
_msg = std::move(msg);
|
||||
}
|
||||
|
||||
if ( !valid ) {
|
||||
if ( blankErr )
|
||||
void LastError::recordInsert(long long nObjects) {
|
||||
reset(true);
|
||||
_nObjects = nObjects;
|
||||
}
|
||||
|
||||
void LastError::recordUpdate(bool updateObjects, long long nObjects, BSONObj upsertedId) {
|
||||
reset(true);
|
||||
_nObjects = nObjects;
|
||||
_updatedExisting = updateObjects ? True : False;
|
||||
if ( upsertedId.valid() && upsertedId.hasField(kUpsertedFieldName) )
|
||||
_upsertedId = upsertedId;
|
||||
}
|
||||
|
||||
void LastError::recordDelete(long long nDeleted) {
|
||||
reset(true);
|
||||
_nObjects = nDeleted;
|
||||
}
|
||||
|
||||
bool LastError::appendSelf(BSONObjBuilder &b , bool blankErr) const {
|
||||
|
||||
if (!_valid) {
|
||||
if (blankErr)
|
||||
b.appendNull( "err" );
|
||||
b.append( "n", 0 );
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( msg.empty() ) {
|
||||
if ( blankErr ) {
|
||||
if (_msg.empty()) {
|
||||
if (blankErr) {
|
||||
b.appendNull( "err" );
|
||||
}
|
||||
}
|
||||
else {
|
||||
b.append( "err", msg );
|
||||
b.append("err", _msg);
|
||||
}
|
||||
|
||||
if ( code )
|
||||
b.append( "code" , code );
|
||||
if ( updatedExisting != NotUpdate )
|
||||
b.appendBool( "updatedExisting", updatedExisting == True );
|
||||
if ( !upsertedId.isEmpty() ) {
|
||||
b.append( upsertedId[kUpsertedFieldName] );
|
||||
if (_code)
|
||||
b.append("code" , _code);
|
||||
if (_updatedExisting != NotUpdate)
|
||||
b.appendBool("updatedExisting", _updatedExisting == True);
|
||||
if (!_upsertedId.isEmpty()) {
|
||||
b.append(_upsertedId[kUpsertedFieldName]);
|
||||
}
|
||||
b.appendNumber( "n", nObjects );
|
||||
b.appendNumber("n", _nObjects);
|
||||
|
||||
return ! msg.empty();
|
||||
}
|
||||
|
||||
LastErrorHolder::~LastErrorHolder() {
|
||||
return !_msg.empty();
|
||||
}
|
||||
|
||||
|
||||
LastError * LastErrorHolder::disableForCommand() {
|
||||
LastError *le = _get();
|
||||
uassert(13649, "no operation yet", le);
|
||||
le->disabled = true;
|
||||
le->nPrev--; // caller is a command that shouldn't count as an operation
|
||||
return le;
|
||||
void LastError::disable() {
|
||||
invariant(!_disabled);
|
||||
_disabled = true;
|
||||
_nPrev--; // caller is a command that shouldn't count as an operation
|
||||
}
|
||||
|
||||
LastError * LastErrorHolder::get( bool create ) {
|
||||
LastError *ret = _get( create );
|
||||
if ( ret && !ret->disabled )
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
LastError * LastErrorHolder::getSafe() {
|
||||
LastError * le = get(false);
|
||||
if ( ! le ) {
|
||||
error() << " no LastError!" << std::endl;
|
||||
verify( le );
|
||||
}
|
||||
return le;
|
||||
}
|
||||
|
||||
LastError * LastErrorHolder::_get( bool create ) {
|
||||
LastError * le = _tl.get();
|
||||
if ( ! le && create ) {
|
||||
le = new LastError();
|
||||
_tl.reset( le );
|
||||
}
|
||||
return le;
|
||||
}
|
||||
|
||||
void LastErrorHolder::release() {
|
||||
_tl.release();
|
||||
}
|
||||
|
||||
/** ok to call more than once. */
|
||||
void LastErrorHolder::initThread() {
|
||||
if( ! _tl.get() )
|
||||
_tl.reset( new LastError() );
|
||||
}
|
||||
|
||||
void LastErrorHolder::reset( LastError * le ) {
|
||||
_tl.reset( le );
|
||||
}
|
||||
|
||||
void prepareErrForNewRequest( Message &m, LastError * err ) {
|
||||
// a killCursors message shouldn't affect last error
|
||||
verify( err );
|
||||
if ( m.operation() == dbKillCursors ) {
|
||||
err->disabled = true;
|
||||
}
|
||||
else {
|
||||
err->disabled = false;
|
||||
err->nPrev++;
|
||||
}
|
||||
}
|
||||
|
||||
LastError * LastErrorHolder::startRequest( Message& m , LastError * le ) {
|
||||
verify( le );
|
||||
prepareErrForNewRequest( m, le );
|
||||
return le;
|
||||
void LastError::startRequest() {
|
||||
_disabled = false;
|
||||
++_nPrev;
|
||||
}
|
||||
|
||||
} // namespace mongo
|
||||
|
@ -29,16 +29,13 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <boost/thread/tss.hpp>
|
||||
#include <string>
|
||||
|
||||
#include "mongo/db/client.h"
|
||||
#include "mongo/db/jsobj.h"
|
||||
#include "mongo/bson/oid.h"
|
||||
|
||||
namespace mongo {
|
||||
class BSONObjBuilder;
|
||||
class Message;
|
||||
|
||||
static const char kUpsertedFieldName[] = "upserted";
|
||||
static const char kGLEStatsFieldName[] = "$gleStats";
|
||||
@ -46,107 +43,80 @@ namespace mongo {
|
||||
static const char kGLEStatsLastOpTimeTermFieldName[] = "lastOpTimeTerm";
|
||||
static const char kGLEStatsElectionIdFieldName[] = "electionId";
|
||||
|
||||
struct LastError {
|
||||
int code;
|
||||
std::string msg;
|
||||
enum UpdatedExistingType { NotUpdate, True, False } updatedExisting;
|
||||
// _id field value from inserted doc, returned as kUpsertedFieldName (above)
|
||||
BSONObj upsertedId;
|
||||
long long nObjects;
|
||||
int nPrev;
|
||||
bool valid;
|
||||
bool disabled;
|
||||
void raiseError(int _code , const char *_msg) {
|
||||
reset( true );
|
||||
code = _code;
|
||||
msg = _msg;
|
||||
}
|
||||
void recordUpdate( bool _updateObjects , long long _nObjects , BSONObj _upsertedId ) {
|
||||
reset( true );
|
||||
nObjects = _nObjects;
|
||||
updatedExisting = _updateObjects ? True : False;
|
||||
if ( _upsertedId.valid() && _upsertedId.hasField(kUpsertedFieldName) )
|
||||
upsertedId = _upsertedId;
|
||||
|
||||
}
|
||||
void recordDelete( long long nDeleted ) {
|
||||
reset( true );
|
||||
nObjects = nDeleted;
|
||||
}
|
||||
LastError() {
|
||||
reset();
|
||||
}
|
||||
void reset( bool _valid = false ) {
|
||||
code = 0;
|
||||
msg.clear();
|
||||
updatedExisting = NotUpdate;
|
||||
nObjects = 0;
|
||||
nPrev = 1;
|
||||
valid = _valid;
|
||||
disabled = false;
|
||||
upsertedId = BSONObj();
|
||||
}
|
||||
class LastError {
|
||||
public:
|
||||
static const Client::Decoration<LastError> get;
|
||||
|
||||
/**
|
||||
* @return if there is an err
|
||||
* Resets the object to a newly constructed state. If "valid" is true, marks the last-error
|
||||
* object as "valid".
|
||||
*/
|
||||
bool appendSelf( BSONObjBuilder &b , bool blankErr = true );
|
||||
void reset(bool valid = false);
|
||||
|
||||
struct Disabled : boost::noncopyable {
|
||||
Disabled( LastError * le ) {
|
||||
_le = le;
|
||||
if ( _le ) {
|
||||
_prev = _le->disabled;
|
||||
_le->disabled = true;
|
||||
}
|
||||
else {
|
||||
_prev = false;
|
||||
}
|
||||
/**
|
||||
* when db receives a message/request, call this
|
||||
*/
|
||||
void startRequest();
|
||||
|
||||
/**
|
||||
* Disables error recording for the current operation.
|
||||
*/
|
||||
void disable();
|
||||
|
||||
/**
|
||||
* Sets the error information for the current operation, if error recording was not
|
||||
* explicitly disabled via a call to disable() since the call to startRequest.
|
||||
*/
|
||||
void setLastError(int code, std::string msg);
|
||||
|
||||
void recordInsert(long long nObjects);
|
||||
|
||||
void recordUpdate(bool updateObjects, long long nObjects, BSONObj upsertedId);
|
||||
|
||||
void recordDelete(long long nDeleted);
|
||||
|
||||
/**
|
||||
* Writes the last-error state described by this object to "b".
|
||||
*
|
||||
* If "blankErr" is true, the "err" field will be explicitly set to null in the result
|
||||
* instead of being omitted when the error string is empty.
|
||||
*
|
||||
* Returns true if there is a non-empty error message.
|
||||
*/
|
||||
bool appendSelf(BSONObjBuilder &b, bool blankErr) const;
|
||||
|
||||
bool isValid() const { return _valid; }
|
||||
int const getNPrev() const { return _nPrev; }
|
||||
|
||||
class Disabled {
|
||||
public:
|
||||
explicit Disabled(LastError* le) : _le(le), _prev(le->_disabled) {
|
||||
_le->_disabled = true;
|
||||
}
|
||||
|
||||
~Disabled() {
|
||||
if ( _le )
|
||||
_le->disabled = _prev;
|
||||
_le->_disabled = _prev;
|
||||
}
|
||||
|
||||
LastError * _le;
|
||||
bool _prev;
|
||||
private:
|
||||
LastError * const _le;
|
||||
const bool _prev;
|
||||
};
|
||||
|
||||
static LastError noError;
|
||||
|
||||
private:
|
||||
enum UpdatedExistingType { NotUpdate, True, False };
|
||||
|
||||
int _code = 0;
|
||||
std::string _msg = {};
|
||||
UpdatedExistingType _updatedExisting = NotUpdate;
|
||||
// _id field value from inserted doc, returned as kUpsertedFieldName (above)
|
||||
BSONObj _upsertedId = {};
|
||||
long long _nObjects = 0;
|
||||
int _nPrev = 1;
|
||||
bool _valid = false;
|
||||
bool _disabled = false;
|
||||
};
|
||||
|
||||
extern class LastErrorHolder {
|
||||
public:
|
||||
LastErrorHolder(){}
|
||||
~LastErrorHolder();
|
||||
|
||||
LastError * get( bool create = false );
|
||||
LastError * getSafe();
|
||||
LastError * _get( bool create = false ); // may return a disabled LastError
|
||||
|
||||
void reset( LastError * le );
|
||||
|
||||
/** ok to call more than once. */
|
||||
void initThread();
|
||||
|
||||
void release();
|
||||
|
||||
/** when db receives a message/request, call this */
|
||||
LastError * startRequest( Message& m , LastError * connectionOwned );
|
||||
|
||||
// used to disable lastError reporting while processing a killCursors message
|
||||
// disable causes get() to return 0.
|
||||
LastError *disableForCommand(); // only call once per command invocation!
|
||||
private:
|
||||
boost::thread_specific_ptr<LastError> _tl;
|
||||
|
||||
struct Status {
|
||||
time_t time;
|
||||
LastError *lerr;
|
||||
};
|
||||
} lastError;
|
||||
|
||||
void setLastError(int code , const char *msg);
|
||||
|
||||
} // namespace mongo
|
||||
|
@ -34,6 +34,7 @@
|
||||
|
||||
#include "mongo/db/ops/update_result.h"
|
||||
|
||||
#include "mongo/db/lasterror.h"
|
||||
#include "mongo/util/log.h"
|
||||
|
||||
namespace mongo {
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include "mongo/db/db_raii.h"
|
||||
#include "mongo/db/dbhelpers.h"
|
||||
#include "mongo/db/jsobj.h"
|
||||
#include "mongo/db/lasterror.h"
|
||||
#include "mongo/db/operation_context_impl.h"
|
||||
#include "mongo/db/query/internal_plans.h"
|
||||
#include "mongo/db/repl/is_master_response.h"
|
||||
@ -216,7 +217,7 @@ namespace repl {
|
||||
authenticated.
|
||||
*/
|
||||
if ( cmdObj["forShell"].trueValue() )
|
||||
lastError.disableForCommand();
|
||||
LastError::get(txn->getClient()).disable();
|
||||
|
||||
appendReplicationInfo(txn, result, 0);
|
||||
|
||||
|
@ -41,6 +41,7 @@
|
||||
#include "mongo/db/auth/authorization_session.h"
|
||||
#include "mongo/db/commands.h"
|
||||
#include "mongo/db/dbhelpers.h"
|
||||
#include "mongo/db/lasterror.h"
|
||||
#include "mongo/db/service_context.h"
|
||||
#include "mongo/db/op_observer.h"
|
||||
#include "mongo/db/repl/initial_sync.h"
|
||||
@ -152,7 +153,7 @@ namespace repl {
|
||||
string& errmsg,
|
||||
BSONObjBuilder& result) {
|
||||
if ( cmdObj["forShell"].trueValue() )
|
||||
lastError.disableForCommand();
|
||||
LastError::get(txn->getClient()).disable();
|
||||
|
||||
Status status = getGlobalReplicationCoordinator()->checkReplEnabledForCommand(&result);
|
||||
if (!status.isOK())
|
||||
|
@ -33,6 +33,7 @@
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "mongo/db/client.h"
|
||||
#include "mongo/db/db.h"
|
||||
#include "mongo/db/dbdirectclient.h"
|
||||
#include "mongo/db/json.h"
|
||||
@ -49,15 +50,11 @@ namespace DirectClientTests {
|
||||
class ClientBase {
|
||||
public:
|
||||
ClientBase() {
|
||||
_prevError = mongo::lastError._get( false );
|
||||
mongo::lastError.release();
|
||||
mongo::lastError.reset( new LastError() );
|
||||
mongo::LastError::get(cc()).reset();
|
||||
}
|
||||
virtual ~ClientBase() {
|
||||
mongo::lastError.reset( _prevError );
|
||||
mongo::LastError::get(cc()).reset();
|
||||
}
|
||||
private:
|
||||
LastError* _prevError;
|
||||
};
|
||||
|
||||
const char *ns = "a.b";
|
||||
|
@ -49,6 +49,7 @@
|
||||
#include <mutex>
|
||||
|
||||
#include "mongo/config.h"
|
||||
#include "mongo/db/client.h"
|
||||
#include "mongo/db/db.h"
|
||||
#include "mongo/db/dbdirectclient.h"
|
||||
#include "mongo/db/json.h"
|
||||
@ -91,12 +92,10 @@ namespace PerfTests {
|
||||
class ClientBase {
|
||||
public:
|
||||
ClientBase() : _client(&_txn) {
|
||||
_prevError = mongo::lastError._get( false );
|
||||
mongo::lastError.release();
|
||||
mongo::lastError.reset( new LastError() );
|
||||
mongo::LastError::get(_txn.getClient()).reset();
|
||||
}
|
||||
virtual ~ClientBase() {
|
||||
mongo::lastError.reset( _prevError );
|
||||
mongo::LastError::get(_txn.getClient()).reset();
|
||||
}
|
||||
|
||||
protected:
|
||||
@ -114,7 +113,6 @@ namespace PerfTests {
|
||||
OperationContext* txn() { return &_txn; }
|
||||
|
||||
private:
|
||||
LastError* _prevError;
|
||||
OperationContextImpl _txn;
|
||||
DBDirectClient _client;
|
||||
};
|
||||
|
@ -216,13 +216,11 @@ namespace QueryTests {
|
||||
class ClientBase {
|
||||
public:
|
||||
ClientBase() : _client(&_txn) {
|
||||
_prevError = mongo::lastError._get( false );
|
||||
mongo::lastError.release();
|
||||
mongo::lastError.reset( new LastError() );
|
||||
mongo::LastError::get(_txn.getClient()).reset();
|
||||
_txn.getCurOp()->reset();
|
||||
}
|
||||
virtual ~ClientBase() {
|
||||
mongo::lastError.reset( _prevError );
|
||||
mongo::LastError::get(_txn.getClient()).reset();
|
||||
}
|
||||
|
||||
protected:
|
||||
@ -238,9 +236,6 @@ namespace QueryTests {
|
||||
|
||||
OperationContextImpl _txn;
|
||||
DBDirectClient _client;
|
||||
|
||||
private:
|
||||
LastError* _prevError;
|
||||
};
|
||||
|
||||
class BoundedKey : public ClientBase {
|
||||
|
@ -54,12 +54,10 @@ namespace UpdateTests {
|
||||
class ClientBase {
|
||||
public:
|
||||
ClientBase() : _client(&_txn) {
|
||||
_prevError = mongo::lastError._get( false );
|
||||
mongo::lastError.release();
|
||||
mongo::lastError.reset( new LastError() );
|
||||
mongo::LastError::get(_txn.getClient()).reset();
|
||||
}
|
||||
virtual ~ClientBase() {
|
||||
mongo::lastError.reset( _prevError );
|
||||
mongo::LastError::get(_txn.getClient()).reset();
|
||||
}
|
||||
|
||||
protected:
|
||||
@ -75,9 +73,6 @@ namespace UpdateTests {
|
||||
|
||||
OperationContextImpl _txn;
|
||||
DBDirectClient _client;
|
||||
|
||||
private:
|
||||
LastError* _prevError;
|
||||
};
|
||||
|
||||
class Fail : public ClientBase {
|
||||
|
@ -169,8 +169,9 @@ env.Library(
|
||||
],
|
||||
LIBDEPS=[
|
||||
'$BUILD_DIR/mongo/bson',
|
||||
'cluster_ops',
|
||||
'$BUILD_DIR/mongo/db/common', # for Message
|
||||
'$BUILD_DIR/mongo/lasterror',
|
||||
'cluster_ops',
|
||||
],
|
||||
)
|
||||
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include "mongo/base/owned_pointer_map.h"
|
||||
#include "mongo/client/connpool.h"
|
||||
#include "mongo/client/dbclientcursor.h"
|
||||
#include "mongo/db/client.h"
|
||||
#include "mongo/db/jsobj.h"
|
||||
#include "mongo/db/namespace_string.h"
|
||||
#include "mongo/db/server_options.h"
|
||||
@ -496,6 +497,7 @@ namespace mongo {
|
||||
|
||||
void Balancer::run() {
|
||||
|
||||
Client::initThread("Balancer");
|
||||
// this is the body of a BackgroundJob so if we throw here we're basically ending the balancer thread prematurely
|
||||
while ( ! inShutdown() ) {
|
||||
|
||||
|
@ -532,7 +532,7 @@ namespace {
|
||||
|
||||
bool Chunk::splitIfShould( long dataWritten ) const {
|
||||
dassert( ShouldAutoSplit );
|
||||
LastError::Disabled d( lastError.get() );
|
||||
LastError::Disabled d(&LastError::get(cc()));
|
||||
|
||||
try {
|
||||
_dataWritten += dataWritten;
|
||||
|
@ -282,7 +282,7 @@ namespace {
|
||||
Shard::getAllShards( all );
|
||||
|
||||
// Don't report exceptions here as errors in GetLastError
|
||||
LastError::Disabled ignoreForGLE(lastError.get(false));
|
||||
LastError::Disabled ignoreForGLE(&LastError::get(cc()));
|
||||
|
||||
// Now only check top-level shard connections
|
||||
for ( unsigned i=0; i<all.size(); i++ ) {
|
||||
|
@ -88,12 +88,13 @@ namespace {
|
||||
// about 2.4 behavior?
|
||||
//
|
||||
|
||||
LastError *le = lastError.disableForCommand();
|
||||
invariant(le);
|
||||
LastError *le = &LastError::get(cc());
|
||||
le->disable();
|
||||
|
||||
|
||||
// Write commands always have the error stored in the mongos last error
|
||||
bool errorOccurred = false;
|
||||
if (le->nPrev == 1) {
|
||||
if (le->getNPrev() == 1) {
|
||||
errorOccurred = le->appendSelf(result, false);
|
||||
}
|
||||
|
||||
|
@ -72,7 +72,7 @@ namespace {
|
||||
BSONObjBuilder& result) {
|
||||
|
||||
if (cmdObj["forShell"].trueValue()) {
|
||||
lastError.disableForCommand();
|
||||
LastError::get(cc()).disable();
|
||||
ClusterLastErrorInfo::get(cc()).disableForCommand();
|
||||
}
|
||||
|
||||
|
@ -66,10 +66,7 @@ namespace {
|
||||
std::string& errmsg,
|
||||
BSONObjBuilder& result) {
|
||||
|
||||
LastError* le = lastError.get();
|
||||
if (le) {
|
||||
le->reset();
|
||||
}
|
||||
LastError::get(cc()).reset();
|
||||
|
||||
const std::set<std::string>* shards =
|
||||
ClusterLastErrorInfo::get(cc()).getPrevShardHosts();
|
||||
|
@ -85,7 +85,7 @@ namespace {
|
||||
|
||||
// TODO: Remove this when we standardize GLE reporting from commands
|
||||
if (!status.isOK()) {
|
||||
setLastError(status.code(), status.reason().c_str());
|
||||
LastError::get(client).setLastError(status.code(), status.reason());
|
||||
}
|
||||
|
||||
return status;
|
||||
@ -149,8 +149,7 @@ namespace {
|
||||
|
||||
ClusterWriter writer(true, 0);
|
||||
|
||||
// NOTE: Sometimes this command is invoked with LE disabled for legacy writes
|
||||
LastError* cmdLastError = lastError.get(false);
|
||||
LastError* cmdLastError = &LastError::get(cc());
|
||||
|
||||
{
|
||||
// Disable the last error object for the duration of the write
|
||||
@ -174,11 +173,9 @@ namespace {
|
||||
dassert(response.isValid(NULL));
|
||||
}
|
||||
|
||||
if (cmdLastError) {
|
||||
// Populate the lastError object based on the write response
|
||||
cmdLastError->reset();
|
||||
batchErrorToLastError(request, response, cmdLastError);
|
||||
}
|
||||
// Populate the lastError object based on the write response
|
||||
cmdLastError->reset();
|
||||
batchErrorToLastError(request, response, cmdLastError);
|
||||
|
||||
size_t numAttempts;
|
||||
|
||||
|
@ -282,7 +282,7 @@ namespace mongo {
|
||||
ChunkManagerPtr DBConfig::getChunkManagerIfExists( const string& ns, bool shouldReload, bool forceReload ){
|
||||
|
||||
// Don't report exceptions here as errors in GetLastError
|
||||
LastError::Disabled ignoreForGLE(lastError.get(false));
|
||||
LastError::Disabled ignoreForGLE(&LastError::get(cc()));
|
||||
|
||||
try{
|
||||
return getChunkManager( ns, shouldReload, forceReload );
|
||||
|
@ -46,6 +46,7 @@
|
||||
#include "mongo/db/auth/privilege.h"
|
||||
#include "mongo/db/commands.h"
|
||||
#include "mongo/db/jsobj.h"
|
||||
#include "mongo/db/lasterror.h"
|
||||
#include "mongo/db/max_time.h"
|
||||
#include "mongo/db/server_parameters.h"
|
||||
#include "mongo/util/concurrency/task.h"
|
||||
@ -367,6 +368,7 @@ namespace mongo {
|
||||
}
|
||||
|
||||
void CursorCache::gotKillCursors(Message& m ) {
|
||||
LastError::get(cc()).disable();
|
||||
DbMessage dbmessage(m);
|
||||
int n = dbmessage.pullInt();
|
||||
|
||||
|
@ -48,6 +48,7 @@
|
||||
#include "mongo/db/db.h"
|
||||
#include "mongo/db/db_raii.h"
|
||||
#include "mongo/db/jsobj.h"
|
||||
#include "mongo/db/lasterror.h"
|
||||
#include "mongo/db/operation_context.h"
|
||||
#include "mongo/db/repl/replication_coordinator_global.h"
|
||||
#include "mongo/db/wire_version.h"
|
||||
@ -1028,7 +1029,7 @@ namespace mongo {
|
||||
|
||||
// step 1
|
||||
|
||||
lastError.disableForCommand();
|
||||
LastError::get(txn->getClient()).disable();
|
||||
ShardedConnectionInfo* info = ShardedConnectionInfo::get( true );
|
||||
|
||||
bool authoritative = cmdObj.getBoolField( "authoritative" );
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include "mongo/db/auth/authorization_session.h"
|
||||
#include "mongo/db/client.h"
|
||||
#include "mongo/db/commands.h"
|
||||
#include "mongo/db/lasterror.h"
|
||||
#include "mongo/db/stats/counters.h"
|
||||
#include "mongo/s/cluster_last_error_info.h"
|
||||
#include "mongo/s/cursors.h"
|
||||
@ -67,6 +68,7 @@ namespace mongo {
|
||||
}
|
||||
|
||||
_m.header().setId(_id);
|
||||
LastError::get(_clientInfo).startRequest();
|
||||
ClusterLastErrorInfo::get(_clientInfo).clearRequestInfo();
|
||||
|
||||
if (_d.messageShouldHaveNs()) {
|
||||
|
@ -142,13 +142,10 @@ namespace mongo {
|
||||
Client::initThread("conn", getGlobalServiceContext(), p);
|
||||
}
|
||||
|
||||
virtual void process( Message& m , AbstractMessagingPort* p , LastError * le) {
|
||||
virtual void process(Message& m, AbstractMessagingPort* p) {
|
||||
verify( p );
|
||||
Request r( m , p );
|
||||
|
||||
verify( le );
|
||||
lastError.startRequest( m , le );
|
||||
|
||||
try {
|
||||
r.init();
|
||||
r.process();
|
||||
@ -165,7 +162,7 @@ namespace mongo {
|
||||
}
|
||||
|
||||
// We *always* populate the last error for now
|
||||
le->raiseError( ex.getCode() , ex.what() );
|
||||
LastError::get(cc()).setLastError(ex.getCode(), ex.what());
|
||||
}
|
||||
catch ( const DBException& ex ) {
|
||||
|
||||
@ -179,7 +176,7 @@ namespace mongo {
|
||||
}
|
||||
|
||||
// We *always* populate the last error for now
|
||||
le->raiseError( ex.getCode() , ex.what() );
|
||||
LastError::get(cc()).setLastError(ex.getCode(), ex.what());
|
||||
}
|
||||
|
||||
// Release connections back to pool, if any still cached
|
||||
|
@ -654,7 +654,7 @@ namespace mongo {
|
||||
void Strategy::writeOp( int op , Request& r ) {
|
||||
|
||||
// make sure we have a last error
|
||||
dassert( lastError.get( false /* don't create */) );
|
||||
dassert(&LastError::get(cc()));
|
||||
|
||||
OwnedPointerVector<BatchedCommandRequest> requestsOwned;
|
||||
vector<BatchedCommandRequest*>& requests = requestsOwned.mutableVector();
|
||||
@ -666,7 +666,7 @@ namespace mongo {
|
||||
|
||||
// Multiple commands registered to last error as multiple requests
|
||||
if ( it != requests.begin() )
|
||||
lastError.startRequest( r.m(), lastError.get( false ) );
|
||||
LastError::get(cc()).startRequest();
|
||||
|
||||
BatchedCommandRequest* request = *it;
|
||||
|
||||
@ -681,7 +681,7 @@ namespace mongo {
|
||||
|
||||
{
|
||||
// Disable the last error object for the duration of the write cmd
|
||||
LastError::Disabled disableLastError( lastError.get( false ) );
|
||||
LastError::Disabled disableLastError(&LastError::get(cc()));
|
||||
Command::runAgainstRegistered( cmdNS.c_str(), requestBSON, builder, 0 );
|
||||
}
|
||||
|
||||
@ -691,8 +691,8 @@ namespace mongo {
|
||||
dassert( parsed && response.isValid( NULL ) );
|
||||
|
||||
// Populate the lastError object based on the write response
|
||||
lastError.get( false )->reset();
|
||||
bool hadError = batchErrorToLastError( *request, response, lastError.get( false ) );
|
||||
LastError::get(cc()).reset();
|
||||
bool hadError = batchErrorToLastError(*request, response, &LastError::get(cc()));
|
||||
|
||||
// Check if this is an ordered batch and we had an error which should stop processing
|
||||
if ( request->getOrdered() && hadError )
|
||||
|
@ -203,8 +203,8 @@ namespace mongo {
|
||||
// Record an error if one exists
|
||||
if ( lastBatchError ) {
|
||||
string errMsg = lastBatchError->getErrMessage();
|
||||
error->raiseError( lastBatchError->getErrCode(),
|
||||
errMsg.empty() ? "see code for details" : errMsg.c_str() );
|
||||
error->setLastError(lastBatchError->getErrCode(),
|
||||
errMsg.empty() ? "see code for details" : errMsg.c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
* exception statement from all source files in the program, then also delete
|
||||
* it in the license file.
|
||||
*/
|
||||
#include "mongo/platform/basic.h"
|
||||
|
||||
#include "mongo/s/write_ops/batch_upconvert.h"
|
||||
|
||||
|
@ -424,10 +424,6 @@ string finishCode( string code ) {
|
||||
return code;
|
||||
}
|
||||
|
||||
namespace mongo {
|
||||
extern bool isShell;
|
||||
}
|
||||
|
||||
bool execPrompt( mongo::Scope &scope, const char *promptFunction, string &prompt ) {
|
||||
string execStatement = string( "__prompt__ = " ) + promptFunction + "();";
|
||||
scope.exec( "delete __prompt__;", "", false, false, false, 0 );
|
||||
@ -588,7 +584,6 @@ static void edit( const string& whatToEdit ) {
|
||||
}
|
||||
|
||||
int _main( int argc, char* argv[], char **envp ) {
|
||||
mongo::isShell = true;
|
||||
setupSignalHandlers(true);
|
||||
setupSignals();
|
||||
|
||||
|
@ -38,8 +38,6 @@
|
||||
|
||||
namespace mongo {
|
||||
|
||||
struct LastError;
|
||||
|
||||
class MessageHandler {
|
||||
public:
|
||||
virtual ~MessageHandler() {}
|
||||
@ -53,7 +51,7 @@ namespace mongo {
|
||||
* called every time a message comes in
|
||||
* handler is responsible for responding to client
|
||||
*/
|
||||
virtual void process( Message& m , AbstractMessagingPort* p , LastError * err ) = 0;
|
||||
virtual void process(Message& m, AbstractMessagingPort* p) = 0;
|
||||
};
|
||||
|
||||
class MessageServer {
|
||||
|
@ -207,9 +207,6 @@ namespace {
|
||||
Message m;
|
||||
int64_t counter = 0;
|
||||
try {
|
||||
LastError * le = new LastError();
|
||||
lastError.reset( le ); // lastError now has ownership
|
||||
|
||||
handler->connected(portWithHandler.get());
|
||||
|
||||
while ( ! inShutdown() ) {
|
||||
@ -227,7 +224,7 @@ namespace {
|
||||
break;
|
||||
}
|
||||
|
||||
handler->process(m, portWithHandler.get(), le);
|
||||
handler->process(m, portWithHandler.get());
|
||||
networkCounter.hit(portWithHandler->psock->getBytesIn(),
|
||||
portWithHandler->psock->getBytesOut());
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user