diff options
author | Greg Studer <greg@10gen.com> | 2013-11-11 18:02:26 -0500 |
---|---|---|
committer | Greg Studer <greg@10gen.com> | 2013-11-11 23:11:07 +0000 |
commit | 93f76a53ba6e6c779604c1bfb0581b69c86a0c4f (patch) | |
tree | 3ddda7274079184bda5d3f1e73df3da40cdb9eae /src/mongo/s/write_ops/batch_write_op.h | |
parent | a2dbf35932d0cdd1fe54eb11a36f9bcde60b7333 (diff) | |
download | mongo-93f76a53ba6e6c779604c1bfb0581b69c86a0c4f.tar.gz |
SERVER-10818 reorganize all the write commmand stuff in a folder
Diffstat (limited to 'src/mongo/s/write_ops/batch_write_op.h')
-rw-r--r-- | src/mongo/s/write_ops/batch_write_op.h | 258 |
1 files changed, 258 insertions, 0 deletions
diff --git a/src/mongo/s/write_ops/batch_write_op.h b/src/mongo/s/write_ops/batch_write_op.h new file mode 100644 index 00000000000..ec248b88f37 --- /dev/null +++ b/src/mongo/s/write_ops/batch_write_op.h @@ -0,0 +1,258 @@ +/** + * Copyright (C) 2013 MongoDB Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * As a special exception, the copyright holders give permission to link the + * code of portions of this program with the OpenSSL library under certain + * conditions as described in each individual source file and distribute + * linked combinations including the program with the OpenSSL library. You + * must comply with the GNU Affero General Public License in all respects for + * all of the code used other than as permitted herein. If you modify file(s) + * with this exception, you may extend this exception to your version of the + * file(s), but you are not obligated to do so. If you do not wish to do so, + * delete this exception statement from your version. If you delete this + * exception statement from all source files in the program, then also delete + * it in the license file. + */ + +#pragma once + +#include <set> +#include <vector> + +#include "mongo/base/disallow_copying.h" +#include "mongo/base/owned_pointer_vector.h" +#include "mongo/base/status.h" +#include "mongo/platform/unordered_map.h" +#include "mongo/s/ns_targeter.h" +#include "mongo/s/write_ops/batched_command_request.h" +#include "mongo/s/write_ops/batched_command_response.h" +#include "mongo/s/write_ops/batched_error_detail.h" +#include "mongo/s/write_ops/write_op.h" + +namespace mongo { + + class TargetedWriteBatch; + struct ShardError; + class TrackedErrors; + class BatchWriteStats; + + /** + * The BatchWriteOp class manages the lifecycle of a batched write received by mongos. Each + * item in a batch is tracked via a WriteOp, and the function of the BatchWriteOp is to + * aggregate the dispatched requests and responses for the underlying WriteOps. + * + * Overall, the BatchWriteOp lifecycle is similar to the WriteOp lifecycle, with the following + * stages: + * + * 0) Client request comes in, batch write op is initialized + * + * 1a) One or more ops in the batch are targeted using targetBatch, resulting in + * TargetedWriteBatches for these ops. + * 1b) There are targeting errors, and the batch must be retargeted after refreshing the + * NSTargeter. + * + * 2) (Child BatchCommandRequests are be built for each TargetedWriteBatch before sending) + * + * 3) Responses for sent TargetedWriteBatches are noted, errors are stored and aggregated per- + * write-op. Errors the caller is interested in are returned. + * + * 4) If the batch write is not finished, goto 0 + * + * 5) When all responses come back for all write ops, errors are aggregated and returned in + * a client response + * + */ + class BatchWriteOp { + MONGO_DISALLOW_COPYING(BatchWriteOp); + public: + + BatchWriteOp(); + + ~BatchWriteOp(); + + /** + * Initializes the BatchWriteOp from a client batch request. + */ + void initClientRequest( const BatchedCommandRequest* clientRequest ); + + /** + * Targets one or more of the next write ops in this batch op using a NSTargeter. The + * resulting TargetedWrites are aggregated together in the returned TargetedWriteBatches. + * + * If 'recordTargetErrors' is false, any targeting error will abort all current batches and + * the method will return the targeting error. No targetedBatches will be returned on + * error. + * + * Otherwise, if 'recordTargetErrors' is true, targeting errors will be recorded for each + * write op that fails to target, and the method will return OK. + * + * (The idea here is that if we are sure our NSTargeter is up-to-date we should record + * targeting errors, but if not we should refresh once first.) + * + * Returned TargetedWriteBatches are owned by the caller. + */ + Status targetBatch( const NSTargeter& targeter, + bool recordTargetErrors, + vector<TargetedWriteBatch*>* targetedBatches ); + + /** + * Fills a BatchCommandRequest from a TargetedWriteBatch for this BatchWriteOp. + */ + void buildBatchRequest( const TargetedWriteBatch& targetedBatch, + BatchedCommandRequest* request ) const; + + /** + * Stores a response from one of the outstanding TargetedWriteBatches for this BatchWriteOp. + * The response may be in any form, error or not. + * + * There is an additional optional 'trackedErrors' parameter, which can be used to return + * copies of any errors in the response that the caller is interested in (specified by + * errCode). (This avoids external callers needing to know much about the response format.) + */ + void noteBatchResponse( const TargetedWriteBatch& targetedBatch, + const BatchedCommandResponse& response, + TrackedErrors* trackedErrors ); + + /** + * Stores an error that occurred while trying to send/recv a TargetedWriteBatch for this + * BatchWriteOp, and so a response is not available. + */ + void noteBatchError( const TargetedWriteBatch& targetedBatch, + const BatchedErrorDetail& error ); + + /** + * Returns false if the batch write op needs more processing. + */ + bool isFinished(); + + /** + * Fills a batch response to send back to the client. + */ + void buildClientResponse( BatchedCommandResponse* batchResp ); + + private: + + // Incoming client request, not owned here + const BatchedCommandRequest* _clientRequest; + + // Array of ops being processed from the client request + WriteOp* _writeOps; + + // Current outstanding batch op write requests + // Not owned here but tracked for reporting + std::set<const TargetedWriteBatch*> _targeted; + + // Write concern responses from all write batches so far + OwnedPointerVector<ShardError> _wcErrors; + + // Upserted ids for the whole write batch + OwnedPointerVector<BatchedUpsertDetail> _upsertedIds; + + // Stats for the entire batch op + scoped_ptr<BatchWriteStats> _stats; + }; + + struct BatchWriteStats { + + BatchWriteStats(); + + int numInserted; + int numUpserted; + int numUpdated; + int numDeleted; + + }; + + /** + * Data structure representing the information needed to make a batch request, along with + * pointers to where the resulting responses should be placed. + * + * Internal support for storage as a doubly-linked list, to allow the TargetedWriteBatch to + * efficiently be registered for reporting. + */ + class TargetedWriteBatch { + MONGO_DISALLOW_COPYING(TargetedWriteBatch); + public: + + TargetedWriteBatch( const ShardEndpoint& endpoint ) : + _endpoint( endpoint ) { + } + + const ShardEndpoint& getEndpoint() const { + return _endpoint; + } + + /** + * TargetedWrite is owned here once given to the TargetedWriteBatch + */ + void addWrite( TargetedWrite* targetedWrite ) { + _writes.mutableVector().push_back( targetedWrite ); + } + + const std::vector<TargetedWrite*>& getWrites() const { + return _writes.vector(); + } + + private: + + // Where to send the batch + const ShardEndpoint _endpoint; + + // Where the responses go + // TargetedWrite*s are owned by the TargetedWriteBatch + OwnedPointerVector<TargetedWrite> _writes; + }; + + /** + * Simple struct for storing an error with an endpoint. + * + * Certain types of errors are not stored in WriteOps or must be returned to a caller. + */ + struct ShardError { + + ShardError( const ShardEndpoint& endpoint, const BatchedErrorDetail& error ) : + endpoint( endpoint ) { + error.cloneTo( &this->error ); + } + + const ShardEndpoint endpoint; + BatchedErrorDetail error; + }; + + /** + * Helper class for tracking certain errors from batch operations + */ + class TrackedErrors { + public: + + ~TrackedErrors(); + + void startTracking( int errCode ); + + bool isTracking( int errCode ) const; + + void addError( ShardError* error ); + + const std::vector<ShardError*>& getErrors( int errCode ) const; + + void clear(); + + private: + + typedef unordered_map<int, std::vector<ShardError*> > TrackedErrorMap; + TrackedErrorMap _errorMap; + }; + +} |