UserNameIterator UserSet::getNames() const { return UserNameIterator(std::make_unique<UserSetNameIteratorImpl>(begin(), end())); }
void CollectionCloner::_establishCollectionCursorsCallback(const RemoteCommandCallbackArgs& rcbd, EstablishCursorsCommand cursorCommand) { if (_state == State::kShuttingDown) { Status shuttingDownStatus{ErrorCodes::CallbackCanceled, "Cloner shutting down."}; _finishCallback(shuttingDownStatus); return; } auto response = rcbd.response; if (!response.isOK()) { _finishCallback(response.status); return; } Status commandStatus = getStatusFromCommandResult(response.data); if (commandStatus == ErrorCodes::NamespaceNotFound) { _finishCallback(Status::OK()); return; } if (!commandStatus.isOK()) { _finishCallback(commandStatus.withContext( str::stream() << "Error querying collection '" << _sourceNss.ns() << "'")); return; } std::vector<CursorResponse> cursorResponses; Status parseResponseStatus = _parseCursorResponse(response.data, &cursorResponses, cursorCommand); if (!parseResponseStatus.isOK()) { _finishCallback(parseResponseStatus); return; } LOG(1) << "Collection cloner running with " << cursorResponses.size() << " cursors established."; // Initialize the 'AsyncResultsMerger'(ARM). std::vector<ClusterClientCursorParams::RemoteCursor> remoteCursors; for (auto&& cursorResponse : cursorResponses) { // A placeholder 'ShardId' is used until the ARM is made less sharding specific. remoteCursors.emplace_back( ShardId("CollectionClonerSyncSource"), _source, std::move(cursorResponse)); } // An empty list of authenticated users is passed into the cluster parameters // as user information is not used in the ARM in context of collection cloning. _clusterClientCursorParams = stdx::make_unique<ClusterClientCursorParams>(_sourceNss, UserNameIterator()); _clusterClientCursorParams->remotes = std::move(remoteCursors); if (_collectionCloningBatchSize > 0) _clusterClientCursorParams->batchSize = _collectionCloningBatchSize; Client::initThreadIfNotAlready(); _arm = stdx::make_unique<AsyncResultsMerger>( cc().getOperationContext(), _executor, _clusterClientCursorParams.get()); // This completion guard invokes _finishCallback on destruction. auto cancelRemainingWorkInLock = [this]() { _cancelRemainingWork_inlock(); }; auto finishCallbackFn = [this](const Status& status) { _finishCallback(status); }; auto onCompletionGuard = std::make_shared<OnCompletionGuard>(cancelRemainingWorkInLock, finishCallbackFn); // Lock guard must be declared after completion guard. If there is an error in this function // that will cause the destructor of the completion guard to run, the destructor must be run // outside the mutex. This is a necessary condition to invoke _finishCallback. stdx::lock_guard<stdx::mutex> lock(_mutex); Status scheduleStatus = _scheduleNextARMResultsCallback(onCompletionGuard); _arm->detachFromOperationContext(); if (!scheduleStatus.isOK()) { onCompletionGuard->setResultAndCancelRemainingWork_inlock(lock, scheduleStatus); return; } }
UserNameIterator UserSet::getNames() const { return UserNameIterator(new UserSetNameIteratorImpl(begin(), end())); }