本文整理汇总了C++中BatchedCommandRequest::isWriteConcernSet方法的典型用法代码示例。如果您正苦于以下问题:C++ BatchedCommandRequest::isWriteConcernSet方法的具体用法?C++ BatchedCommandRequest::isWriteConcernSet怎么用?C++ BatchedCommandRequest::isWriteConcernSet使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类BatchedCommandRequest
的用法示例。
在下文中一共展示了BatchedCommandRequest::isWriteConcernSet方法的8个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: clusterWrite
void clusterWrite( const BatchedCommandRequest& request,
BatchedCommandResponse* response,
bool autoSplit ) {
// App-level validation of a create index insert
if ( request.isInsertIndexRequest() ) {
if ( request.sizeWriteOps() != 1 || request.isWriteConcernSet() ) {
// Invalid request to create index
response->setOk( false );
response->setErrCode( ErrorCodes::InvalidOptions );
response->setErrMessage( "invalid batch request for index creation" );
dassert( response->isValid( NULL ) );
return;
}
}
// Config writes and shard writes are done differently
string dbName = NamespaceString( request.getNS() ).db().toString();
if ( dbName == "config" || dbName == "admin" ) {
bool verboseWC = request.isVerboseWC();
// We only support batch sizes of one and {w:0} write concern for config writes
if ( request.sizeWriteOps() != 1 || ( verboseWC && request.isWriteConcernSet() ) ) {
// Invalid config server write
response->setOk( false );
response->setErrCode( ErrorCodes::InvalidOptions );
response->setErrMessage( "invalid batch request for config write" );
dassert( response->isValid( NULL ) );
return;
}
// We need to support "best-effort" writes for pings to the config server.
// {w:0} (!verbose) writes are interpreted as best-effort in this case - they may still
// error, but do not do the initial fsync check.
configWrite( request, response, verboseWC );
}
else {
shardWrite( request, response, autoSplit );
}
}
示例2: executeBatch
void WriteBatchExecutor::executeBatch( const BatchedCommandRequest& request,
BatchedCommandResponse* response ) {
Timer commandTimer;
WriteStats stats;
std::auto_ptr<BatchedErrorDetail> error( new BatchedErrorDetail );
BSONObj upsertedID = BSONObj();
bool batchSuccess = true;
bool staleBatch = false;
// Apply each batch item, stopping on an error if we were asked to apply the batch
// sequentially.
size_t numBatchOps = request.sizeWriteOps();
bool verbose = request.isVerboseWC();
for ( size_t i = 0; i < numBatchOps; i++ ) {
if ( applyWriteItem( BatchItemRef( &request, i ),
&stats,
&upsertedID,
error.get() ) ) {
// In case updates turned out to be upserts, the callers may be interested
// in learning what _id was used for that document.
if ( !upsertedID.isEmpty() ) {
if ( numBatchOps == 1 ) {
response->setSingleUpserted(upsertedID);
}
else if ( verbose ) {
std::auto_ptr<BatchedUpsertDetail> upsertDetail(new BatchedUpsertDetail);
upsertDetail->setIndex(i);
upsertDetail->setUpsertedID(upsertedID);
response->addToUpsertDetails(upsertDetail.release());
}
upsertedID = BSONObj();
}
}
else {
// The applyWriteItem did not go thgrou
// If the error is sharding related, we'll have to investigate whether we
// have a stale view of sharding state.
if ( error->getErrCode() == ErrorCodes::StaleShardVersion ) staleBatch = true;
// Don't bother recording if the user doesn't want a verbose answer. We want to
// keep the error if this is a one-item batch, since we already compact the
// response for those.
if (verbose || numBatchOps == 1) {
error->setIndex( static_cast<int>( i ) );
response->addToErrDetails( error.release() );
}
batchSuccess = false;
if ( request.getOrdered() ) break;
error.reset( new BatchedErrorDetail );
}
}
// So far, we may have failed some of the batch's items. So we record
// that. Rergardless, we still need to apply the write concern. If that generates a
// more specific error, we'd replace for the intermediate error here. Note that we
// "compatct" the error messge if this is an one-item batch. (See rationale later in
// this file.)
if ( !batchSuccess ) {
if (numBatchOps > 1) {
// TODO
// Define the final error code here.
// Might be used as a final error, depending on write concern success.
response->setErrCode( 99999 );
response->setErrMessage( "batch op errors occurred" );
}
else {
// Promote the single error.
const BatchedErrorDetail* error = response->getErrDetailsAt( 0 );
response->setErrCode( error->getErrCode() );
if ( error->isErrInfoSet() ) response->setErrInfo( error->getErrInfo() );
response->setErrMessage( error->getErrMessage() );
response->unsetErrDetails();
error = NULL;
}
}
// Apply write concern. Note, again, that we're only assembling a full response if the
// user is interested in it.
BSONObj writeConcern;
if ( request.isWriteConcernSet() ) {
writeConcern = request.getWriteConcern();
}
else {
writeConcern = _defaultWriteConcern;
}
string errMsg;
BSONObjBuilder wcResultsB;
if ( !waitForWriteConcern( writeConcern, !batchSuccess, &wcResultsB, &errMsg ) ) {
//.........这里部分代码省略.........
示例3: executeBatch
void WriteBatchExecutor::executeBatch( const BatchedCommandRequest& request,
BatchedCommandResponse* response ) {
// Validate namespace
const NamespaceString nss = NamespaceString( request.getNS() );
if ( !nss.isValid() ) {
toBatchError( Status( ErrorCodes::InvalidNamespace,
nss.ns() + " is not a valid namespace" ),
response );
return;
}
// Make sure we can write to the namespace
Status allowedStatus = userAllowedWriteNS( nss );
if ( !allowedStatus.isOK() ) {
toBatchError( allowedStatus, response );
return;
}
// Validate insert index requests
// TODO: Push insert index requests through createIndex once all upgrade paths support it
string errMsg;
if ( request.isInsertIndexRequest() && !request.isValidIndexRequest( &errMsg ) ) {
toBatchError( Status( ErrorCodes::InvalidOptions, errMsg ), response );
return;
}
// Validate write concern
// TODO: Lift write concern parsing out of this entirely
WriteConcernOptions writeConcern;
BSONObj wcDoc;
if ( request.isWriteConcernSet() ) {
wcDoc = request.getWriteConcern();
}
Status wcStatus = Status::OK();
if ( wcDoc.isEmpty() ) {
// The default write concern if empty is w : 1
// Specifying w : 0 is/was allowed, but is interpreted identically to w : 1
wcStatus = writeConcern.parse(
_defaultWriteConcern.isEmpty() ?
WriteConcernOptions::Acknowledged : _defaultWriteConcern );
if ( writeConcern.wNumNodes == 0 && writeConcern.wMode.empty() ) {
writeConcern.wNumNodes = 1;
}
}
else {
wcStatus = writeConcern.parse( wcDoc );
}
if ( wcStatus.isOK() ) {
wcStatus = validateWriteConcern( writeConcern );
}
if ( !wcStatus.isOK() ) {
toBatchError( wcStatus, response );
return;
}
if ( request.sizeWriteOps() == 0u ) {
toBatchError( Status( ErrorCodes::InvalidLength,
"no write ops were included in the batch" ),
response );
return;
}
// Validate batch size
if ( request.sizeWriteOps() > BatchedCommandRequest::kMaxWriteBatchSize ) {
toBatchError( Status( ErrorCodes::InvalidLength,
stream() << "exceeded maximum write batch size of "
<< BatchedCommandRequest::kMaxWriteBatchSize ),
response );
return;
}
//
// End validation
//
bool silentWC = writeConcern.wMode.empty() && writeConcern.wNumNodes == 0
&& writeConcern.syncMode == WriteConcernOptions::NONE;
Timer commandTimer;
OwnedPointerVector<WriteErrorDetail> writeErrorsOwned;
vector<WriteErrorDetail*>& writeErrors = writeErrorsOwned.mutableVector();
OwnedPointerVector<BatchedUpsertDetail> upsertedOwned;
vector<BatchedUpsertDetail*>& upserted = upsertedOwned.mutableVector();
//
// Apply each batch item, possibly bulking some items together in the write lock.
// Stops on error if batch is ordered.
//
bulkExecute( request, &upserted, &writeErrors );
//.........这里部分代码省略.........
示例4: write
void ClusterWriter::write( const BatchedCommandRequest& request,
BatchedCommandResponse* response ) {
const NamespaceString nss = NamespaceString( request.getNS() );
if ( !nss.isValid() ) {
toBatchError( Status( ErrorCodes::InvalidNamespace,
nss.ns() + " is not a valid namespace" ),
response );
return;
}
if ( !NamespaceString::validCollectionName( nss.coll() ) ) {
toBatchError( Status( ErrorCodes::BadValue,
str::stream() << "invalid collection name " << nss.coll() ),
response );
return;
}
if ( request.sizeWriteOps() > BatchedCommandRequest::kMaxWriteBatchSize ) {
toBatchError( Status( ErrorCodes::FailedToParse,
str::stream() << "exceeded maximum write batch size of "
<< BatchedCommandRequest::kMaxWriteBatchSize ),
response );
return;
}
string errMsg;
if ( request.isInsertIndexRequest() && !request.isValidIndexRequest( &errMsg ) ) {
toBatchError( Status( ErrorCodes::InvalidOptions, errMsg ), response );
return;
}
// Config writes and shard writes are done differently
string dbName = nss.db().toString();
if ( dbName == "config" || dbName == "admin" ) {
bool verboseWC = request.isVerboseWC();
// We only support batch sizes of one for config writes
if ( request.sizeWriteOps() != 1 ) {
toBatchError( Status( ErrorCodes::InvalidOptions,
mongoutils::str::stream() << "Writes to config servers must "
"have batch size of 1, found "
<< request.sizeWriteOps() ),
response );
return;
}
// We only support {w: 0}, {w: 1}, and {w: 'majority'} write concern for config writes
if ( request.isWriteConcernSet() && !validConfigWC( request.getWriteConcern() )) {
toBatchError( Status( ErrorCodes::InvalidOptions,
mongoutils::str::stream() << "Invalid write concern for write"
" to config servers: " << request.getWriteConcern() ),
response );
return;
}
// We need to support "best-effort" writes for pings to the config server.
// {w:0} (!verbose) writes are interpreted as best-effort in this case - they may still
// error, but do not do the initial fsync check.
configWrite( request, response, verboseWC );
}
else {
shardWrite( request, response );
}
}
示例5: executeBatch
void WriteBatchExecutor::executeBatch( const BatchedCommandRequest& request,
BatchedCommandResponse* response ) {
// TODO: Lift write concern parsing out of this entirely.
WriteConcernOptions writeConcern;
Status status = Status::OK();
BSONObj wcDoc;
if ( request.isWriteConcernSet() ) {
wcDoc = request.getWriteConcern();
}
if ( wcDoc.isEmpty() ) {
status = writeConcern.parse( _defaultWriteConcern );
}
else {
status = writeConcern.parse( wcDoc );
}
if ( status.isOK() ) {
status = validateWriteConcern( writeConcern );
}
if ( !status.isOK() ) {
response->setErrCode( status.code() );
response->setErrMessage( status.reason() );
response->setOk( false );
dassert( response->isValid(NULL) );
return;
}
bool silentWC = writeConcern.wMode.empty() && writeConcern.wNumNodes == 0
&& writeConcern.syncMode == WriteConcernOptions::NONE;
Timer commandTimer;
OwnedPointerVector<WriteErrorDetail> writeErrorsOwned;
vector<WriteErrorDetail*>& writeErrors = writeErrorsOwned.mutableVector();
OwnedPointerVector<BatchedUpsertDetail> upsertedOwned;
vector<BatchedUpsertDetail*>& upserted = upsertedOwned.mutableVector();
//
// Apply each batch item, possibly bulking some items together in the write lock.
// Stops on error if batch is ordered.
//
bulkExecute( request, &upserted, &writeErrors );
//
// Try to enforce the write concern if everything succeeded (unordered or ordered)
// OR if something succeeded and we're unordered.
//
auto_ptr<WCErrorDetail> wcError;
bool needToEnforceWC = writeErrors.empty()
|| ( !request.getOrdered()
&& writeErrors.size() < request.sizeWriteOps() );
if ( needToEnforceWC ) {
_client->curop()->setMessage( "waiting for write concern" );
WriteConcernResult res;
status = waitForWriteConcern( writeConcern, _client->getLastOp(), &res );
if ( !status.isOK() ) {
wcError.reset( toWriteConcernError( status, res ) );
}
}
//
// Refresh metadata if needed
//
bool staleBatch = !writeErrors.empty()
&& writeErrors.back()->getErrCode() == ErrorCodes::StaleShardVersion;
if ( staleBatch ) {
const BatchedRequestMetadata* requestMetadata = request.getMetadata();
dassert( requestMetadata );
// Make sure our shard name is set or is the same as what was set previously
if ( shardingState.setShardName( requestMetadata->getShardName() ) ) {
//
// First, we refresh metadata if we need to based on the requested version.
//
ChunkVersion latestShardVersion;
shardingState.refreshMetadataIfNeeded( request.getTargetingNS(),
requestMetadata->getShardVersion(),
&latestShardVersion );
// Report if we're still changing our metadata
// TODO: Better reporting per-collection
if ( shardingState.inCriticalMigrateSection() ) {
noteInCriticalSection( writeErrors.back() );
}
//.........这里部分代码省略.........
示例6: executeBatch
/**
* The core config write functionality.
*
* Config writes run in two passes - the first is a quick check to ensure the config servers
* are all reachable, the second runs the actual write.
*
* TODO: Upgrade and move this logic to the config servers, a state machine implementation
* is probably the next step.
*/
void ConfigCoordinator::executeBatch( const BatchedCommandRequest& clientRequest,
BatchedCommandResponse* clientResponse,
bool fsyncCheck ) {
NamespaceString nss( clientRequest.getNS() );
dassert( nss.db() == "config" || nss.db() == "admin" );
dassert( clientRequest.sizeWriteOps() == 1u );
dassert( !clientRequest.isWriteConcernSet() );
if ( fsyncCheck ) {
//
// Sanity check that all configs are still reachable using fsync, preserving legacy
// behavior
//
OwnedPointerVector<ConfigFsyncResponse> fsyncResponsesOwned;
vector<ConfigFsyncResponse*>& fsyncResponses = fsyncResponsesOwned.mutableVector();
//
// Send side
//
for ( vector<ConnectionString>::iterator it = _configHosts.begin();
it != _configHosts.end(); ++it ) {
ConnectionString& configHost = *it;
FsyncRequest fsyncRequest;
_dispatcher->addCommand( configHost, "admin", fsyncRequest );
}
_dispatcher->sendAll();
//
// Recv side
//
bool fsyncError = false;
while ( _dispatcher->numPending() > 0 ) {
ConnectionString configHost;
fsyncResponses.push_back( new ConfigFsyncResponse( configHost ) );
ConfigFsyncResponse& fsyncResponse = *fsyncResponses.back();
Status dispatchStatus = _dispatcher->recvAny( &configHost,
&fsyncResponse.response );
// We've got to recv everything, no matter what
if ( !dispatchStatus.isOK() ) {
fsyncError = true;
buildFsyncErrorFrom( dispatchStatus, &fsyncResponse.response );
}
else if ( !fsyncResponse.response.getOk() ) {
fsyncError = true;
}
}
if ( fsyncError ) {
combineFsyncErrors( fsyncResponses, clientResponse );
return;
}
else {
fsyncResponsesOwned.clear();
}
}
//
// Do the actual writes
//
BatchedCommandRequest configRequest( clientRequest.getBatchType() );
clientRequest.cloneTo( &configRequest );
configRequest.setNS( nss.coll() );
OwnedPointerVector<ConfigResponse> responsesOwned;
vector<ConfigResponse*>& responses = responsesOwned.mutableVector();
//
// Send the actual config writes
//
// Get as many batches as we can at once
for ( vector<ConnectionString>::iterator it = _configHosts.begin();
it != _configHosts.end(); ++it ) {
ConnectionString& configHost = *it;
_dispatcher->addCommand( configHost, nss.db(), configRequest );
}
// Send them all out
_dispatcher->sendAll();
//
// Recv side
//.........这里部分代码省略.........
示例7: safeWriteBatch
void BatchSafeWriter::safeWriteBatch( DBClientBase* conn,
const BatchedCommandRequest& request,
BatchedCommandResponse* response ) {
const NamespaceString nss( request.getNS() );
// N starts at zero, and we add to it for each item
response->setN( 0 );
for ( size_t i = 0; i < request.sizeWriteOps(); ++i ) {
// Break on first error if we're ordered
if ( request.getOrdered() && response->isErrDetailsSet() )
break;
BatchItemRef itemRef( &request, static_cast<int>( i ) );
bool isLastItem = ( i == request.sizeWriteOps() - 1 );
BSONObj writeConcern;
if ( isLastItem && request.isWriteConcernSet() ) {
writeConcern = request.getWriteConcern();
// Pre-2.4.2 mongods react badly to 'w' being set on config servers
if ( nss.db() == "config" )
writeConcern = fixWCForConfig( writeConcern );
}
BSONObj gleResult;
GLEErrors errors;
Status status = _safeWriter->safeWrite( conn, itemRef, writeConcern, &gleResult );
if ( status.isOK() ) {
status = extractGLEErrors( gleResult, &errors );
}
if ( !status.isOK() ) {
response->clear();
response->setOk( false );
response->setErrCode( status.code() );
response->setErrMessage( status.reason() );
return;
}
//
// STATS HANDLING
//
GLEStats stats;
extractGLEStats( gleResult, &stats );
// Special case for making legacy "n" field result for insert match the write
// command result.
if ( request.getBatchType() == BatchedCommandRequest::BatchType_Insert
&& !errors.writeError.get() ) {
// n is always 0 for legacy inserts.
dassert( stats.n == 0 );
stats.n = 1;
}
response->setN( response->getN() + stats.n );
if ( !stats.upsertedId.isEmpty() ) {
BatchedUpsertDetail* upsertedId = new BatchedUpsertDetail;
upsertedId->setIndex( i );
upsertedId->setUpsertedID( stats.upsertedId );
response->addToUpsertDetails( upsertedId );
}
response->setLastOp( stats.lastOp );
//
// WRITE ERROR HANDLING
//
// If any error occurs (except stale config) the previous GLE was not enforced
bool enforcedWC = !errors.writeError.get()
|| errors.writeError->getErrCode() == ErrorCodes::StaleShardVersion;
// Save write error
if ( errors.writeError.get() ) {
errors.writeError->setIndex( i );
response->addToErrDetails( errors.writeError.release() );
}
//
// WRITE CONCERN ERROR HANDLING
//
// The last write is weird, since we enforce write concern and check the error through
// the same GLE if possible. If the last GLE was an error, the write concern may not
// have been enforced in that same GLE, so we need to send another after resetting the
// error.
if ( isLastItem ) {
// Try to enforce the write concern if everything succeeded (unordered or ordered)
// OR if something succeeded and we're unordered.
bool needToEnforceWC =
!response->isErrDetailsSet()
|| ( !request.getOrdered()
&& response->sizeErrDetails() < request.sizeWriteOps() );
if ( !enforcedWC && needToEnforceWC ) {
//.........这里部分代码省略.........
示例8: safeWriteBatch
void BatchSafeWriter::safeWriteBatch( DBClientBase* conn,
const BatchedCommandRequest& request,
BatchedCommandResponse* response ) {
const NamespaceString nss( request.getNS() );
// N starts at zero, and we add to it for each item
response->setN( 0 );
// GLE path always sets nModified to -1 (sentinel) to indicate we should omit it later.
response->setNModified(-1);
for ( size_t i = 0; i < request.sizeWriteOps(); ++i ) {
// Break on first error if we're ordered
if ( request.getOrdered() && response->isErrDetailsSet() )
break;
BatchItemRef itemRef( &request, static_cast<int>( i ) );
BSONObj gleResult;
GLEErrors errors;
Status status = _safeWriter->safeWrite( conn,
itemRef,
WriteConcernOptions::Acknowledged,
&gleResult );
if ( status.isOK() ) {
status = extractGLEErrors( gleResult, &errors );
}
if ( !status.isOK() ) {
response->clear();
response->setOk( false );
response->setErrCode( ErrorCodes::RemoteResultsUnavailable );
StringBuilder builder;
builder << "could not get write error from safe write";
builder << causedBy( status.toString() );
response->setErrMessage( builder.str() );
return;
}
if ( errors.wcError.get() ) {
response->setWriteConcernError( errors.wcError.release() );
}
//
// STATS HANDLING
//
GLEStats stats;
extractGLEStats( gleResult, &stats );
// Special case for making legacy "n" field result for insert match the write
// command result.
if ( request.getBatchType() == BatchedCommandRequest::BatchType_Insert
&& !errors.writeError.get() ) {
// n is always 0 for legacy inserts.
dassert( stats.n == 0 );
stats.n = 1;
}
response->setN( response->getN() + stats.n );
if ( !stats.upsertedId.isEmpty() ) {
BatchedUpsertDetail* upsertedId = new BatchedUpsertDetail;
upsertedId->setIndex( i );
upsertedId->setUpsertedID( stats.upsertedId );
response->addToUpsertDetails( upsertedId );
}
response->setLastOp( stats.lastOp );
// Save write error
if ( errors.writeError.get() ) {
errors.writeError->setIndex( i );
response->addToErrDetails( errors.writeError.release() );
}
}
//
// WRITE CONCERN ERROR HANDLING
//
// The last write is weird, since we enforce write concern and check the error through
// the same GLE if possible. If the last GLE was an error, the write concern may not
// have been enforced in that same GLE, so we need to send another after resetting the
// error.
BSONObj writeConcern;
if ( request.isWriteConcernSet() ) {
writeConcern = request.getWriteConcern();
// Pre-2.4.2 mongods react badly to 'w' being set on config servers
if ( nss.db() == "config" )
writeConcern = fixWCForConfig( writeConcern );
}
bool needToEnforceWC = WriteConcernOptions::Acknowledged.woCompare(writeConcern) != 0 &&
WriteConcernOptions::Unacknowledged.woCompare(writeConcern) != 0;
//.........这里部分代码省略.........