void ClusterCursorManager::shutdown() { stdx::unique_lock<stdx::mutex> lk(_mutex); _inShutdown = true; lk.unlock(); killAllCursors(); reapZombieCursors(); }
std::vector<DocumentSourceMergeCursors::CursorDescriptor> ClusterAggregate::parseCursors( const std::vector<Strategy::CommandResult>& shardResults) { try { std::vector<DocumentSourceMergeCursors::CursorDescriptor> cursors; for (size_t i = 0; i < shardResults.size(); i++) { BSONObj result = shardResults[i].result; if (!result["ok"].trueValue()) { // If the failure of the sharded command can be accounted to a single error, // throw a UserException with that error code; otherwise, throw with a // location uassert code. int errCode = getUniqueCodeFromCommandResults(shardResults); if (errCode == 0) { errCode = 17022; } invariant(errCode == result["code"].numberInt() || errCode == 17022); uasserted(errCode, str::stream() << "sharded pipeline failed on shard " << shardResults[i].shardTargetId << ": " << result.toString()); } BSONObj cursor = result["cursor"].Obj(); massert(17023, str::stream() << "shard " << shardResults[i].shardTargetId << " returned non-empty first batch", cursor["firstBatch"].Obj().isEmpty()); massert(17024, str::stream() << "shard " << shardResults[i].shardTargetId << " returned cursorId 0", cursor["id"].Long() != 0); massert(17025, str::stream() << "shard " << shardResults[i].shardTargetId << " returned invalid ns: " << cursor["ns"], NamespaceString(cursor["ns"].String()).isValid()); cursors.emplace_back( shardResults[i].target, cursor["ns"].String(), cursor["id"].Long()); } return cursors; } catch (...) { // Need to clean up any cursors we successfully created on the shards killAllCursors(shardResults); throw; } }