bool run(OperationContext* txn, const string& db, BSONObj& cmdObj, int, string& errmsg, BSONObjBuilder& result, bool fromRepl) { LastError* le = lastError.get(); verify(le); le->reset(); return true; }
bool ClusterWriteCmd::run( const string& dbName, BSONObj& cmdObj, int options, string& errMsg, BSONObjBuilder& result, bool ) { BatchedCommandRequest request( _writeType ); BatchedCommandResponse response; // TODO: if we do namespace parsing, push this to the type if ( !request.parseBSON( cmdObj, &errMsg ) || !request.isValid( &errMsg ) ) { // Batch parse failure response.setOk( false ); response.setErrCode( ErrorCodes::FailedToParse ); response.setErrMessage( errMsg ); dassert( response.isValid( &errMsg ) ); } else { // Fixup the namespace to be a full ns internally NamespaceString nss( dbName, request.getNS() ); request.setNS( nss.ns() ); clusterWrite( request, &response, true /* autosplit */ ); } // Populate the lastError object based on the write dassert( response.isValid( NULL ) ); LastError* lastErrorForRequest = lastError.get( true /* create */ ); dassert( lastErrorForRequest ); lastErrorForRequest->reset(); batchErrorToLastError( request, response, lastErrorForRequest ); // TODO // There's a pending issue about how to report response here. If we use // the command infra-structure, we should reuse the 'errmsg' field. But // we have already filed that message inside the BatchCommandResponse. // return response.getOk(); result.appendElements( response.toBSON() ); return true; }
bool ClusterWriteCmd::run(OperationContext* txn, const string& dbName, BSONObj& cmdObj, int options, string& errMsg, BSONObjBuilder& result, bool ) { BatchedCommandRequest request( _writeType ); BatchedCommandResponse response; ClusterWriter writer( true /* autosplit */, 0 /* timeout */ ); // NOTE: Sometimes this command is invoked with LE disabled for legacy writes LastError* cmdLastError = lastError.get( false ); { // Disable the last error object for the duration of the write LastError::Disabled disableLastError( cmdLastError ); // TODO: if we do namespace parsing, push this to the type if ( !request.parseBSON( cmdObj, &errMsg ) || !request.isValid( &errMsg ) ) { // Batch parse failure response.setOk( false ); response.setErrCode( ErrorCodes::FailedToParse ); response.setErrMessage( errMsg ); } else { // Fixup the namespace to be a full ns internally NamespaceString nss( dbName, request.getNS() ); request.setNS( nss.ns() ); writer.write( request, &response ); } dassert( response.isValid( NULL ) ); } if ( cmdLastError ) { // Populate the lastError object based on the write response cmdLastError->reset(); batchErrorToLastError( request, response, cmdLastError ); } size_t numAttempts; if ( !response.getOk() ) { numAttempts = 0; } else if ( request.getOrdered() && response.isErrDetailsSet() ) { numAttempts = response.getErrDetailsAt(0)->getIndex() + 1; // Add one failed attempt } else { numAttempts = request.sizeWriteOps(); } // TODO: increase opcounters by more than one if ( _writeType == BatchedCommandRequest::BatchType_Insert ) { for( size_t i = 0; i < numAttempts; ++i ) { globalOpCounters.gotInsert(); } } else if ( _writeType == BatchedCommandRequest::BatchType_Update ) { for( size_t i = 0; i < numAttempts; ++i ) { globalOpCounters.gotUpdate(); } } else if ( _writeType == BatchedCommandRequest::BatchType_Delete ) { for( size_t i = 0; i < numAttempts; ++i ) { globalOpCounters.gotDelete(); } } // Save the last opTimes written on each shard for this client, to allow GLE to work if ( ClientInfo::exists() && writer.getStats().hasShardStats() ) { ClientInfo* clientInfo = ClientInfo::get( NULL ); clientInfo->addHostOpTimes( writer.getStats().getShardStats().getWriteOpTimes() ); } // TODO // There's a pending issue about how to report response here. If we use // the command infra-structure, we should reuse the 'errmsg' field. But // we have already filed that message inside the BatchCommandResponse. // return response.getOk(); result.appendElements( response.toBSON() ); return true; }