1 2 /** 3 * Copyright (C) 2018-present MongoDB, Inc. 4 * 5 * This program is free software: you can redistribute it and/or modify 6 * it under the terms of the Server Side Public License, version 1, 7 * as published by MongoDB, Inc. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * Server Side Public License for more details. 13 * 14 * You should have received a copy of the Server Side Public License 15 * along with this program. If not, see 16 * <http://www.mongodb.com/licensing/server-side-public-license>. 17 * 18 * As a special exception, the copyright holders give permission to link the 19 * code of portions of this program with the OpenSSL library under certain 20 * conditions as described in each individual source file and distribute 21 * linked combinations including the program with the OpenSSL library. You 22 * must comply with the Server Side Public License in all respects for 23 * all of the code used other than as permitted herein. If you modify file(s) 24 * with this exception, you may extend this exception to your version of the 25 * file(s), but you are not obligated to do so. If you do not wish to do so, 26 * delete this exception statement from your version. If you delete this 27 * exception statement from all source files in the program, then also delete 28 * it in the license file. 29 */ 30 31 #pragma once 32 33 #include <boost/optional.hpp> 34 #include <functional> 35 #include <memory> 36 #include <vector> 37 38 #include "mongo/bson/bsonobj.h" 39 #include "mongo/client/read_preference.h" 40 #include "mongo/db/auth/user_name.h" 41 #include "mongo/db/cursor_id.h" 42 #include "mongo/db/namespace_string.h" 43 #include "mongo/db/pipeline/pipeline.h" 44 #include "mongo/db/query/cursor_response.h" 45 #include "mongo/db/query/tailable_mode.h" 46 #include "mongo/s/client/shard.h" 47 #include "mongo/util/net/hostandport.h" 48 49 namespace mongo { 50 namespace executor { 51 class TaskExecutor; 52 } 53 54 class OperationContext; 55 class RouterExecStage; 56 57 /** 58 * The resulting ClusterClientCursor will take ownership of the existing remote cursor, generating 59 * results based on the cursor's current state. 60 * 61 * Note that any results already generated from this cursor will not be returned by the resulting 62 * ClusterClientCursor. The caller is responsible for ensuring that results previously generated by 63 * this cursor have been processed. 64 */ 65 struct ClusterClientCursorParams { 66 // When mongos has to do a merge in order to return results to the client in the correct sort 67 // order, it requests a sortKey meta-projection using this field name. 68 static const char kSortKeyField[]; 69 70 struct RemoteCursor { RemoteCursorClusterClientCursorParams::RemoteCursor71 RemoteCursor(ShardId shardId, HostAndPort hostAndPort, CursorResponse cursorResponse) 72 : shardId(std::move(shardId)), 73 hostAndPort(std::move(hostAndPort)), 74 cursorResponse(std::move(cursorResponse)) {} 75 76 // The shardId of the shard on which the cursor resides. 77 ShardId shardId; 78 79 // The exact host (within the shard) on which the cursor resides. 80 HostAndPort hostAndPort; 81 82 // Encompasses the state of the established cursor. 83 CursorResponse cursorResponse; 84 }; 85 86 ClusterClientCursorParams(NamespaceString nss, 87 UserNameIterator authenticatedUsersIter, 88 boost::optional<ReadPreferenceSetting> readPref = boost::none) nsStringClusterClientCursorParams89 : nsString(std::move(nss)) { 90 while (authenticatedUsersIter.more()) { 91 authenticatedUsers.emplace_back(authenticatedUsersIter.next()); 92 } 93 if (readPref) { 94 readPreference = std::move(readPref.get()); 95 } 96 } 97 98 // Namespace against which the cursors exist. 99 NamespaceString nsString; 100 101 // The set of authenticated users when this cursor was created. 102 std::vector<UserName> authenticatedUsers; 103 104 // Per-remote node data. 105 std::vector<RemoteCursor> remotes; 106 107 // The sort specification. Leave empty if there is no sort. 108 BSONObj sort; 109 110 // The number of results to skip. Optional. Should not be forwarded to the remote hosts in 111 // 'cmdObj'. 112 boost::optional<long long> skip; 113 114 // The number of results per batch. Optional. If specified, will be specified as the batch for 115 // each getMore. 116 boost::optional<long long> batchSize; 117 118 // Limits the number of results returned by the ClusterClientCursor to this many. Optional. 119 // Should be forwarded to the remote hosts in 'cmdObj'. 120 boost::optional<long long> limit; 121 122 // If set, we use this pipeline to merge the output of aggregations on each remote. 123 std::unique_ptr<Pipeline, Pipeline::Deleter> mergePipeline; 124 125 // Whether this cursor is tailing a capped collection, and whether it has the awaitData option 126 // set. 127 TailableMode tailableMode = TailableMode::kNormal; 128 129 // Set if a readPreference must be respected throughout the lifetime of the cursor. 130 boost::optional<ReadPreferenceSetting> readPreference; 131 132 // If valid, is called to return the RouterExecStage which becomes the initial source in this 133 // cursor's execution plan. Otherwise, a RouterStageMerge is used. 134 stdx::function<std::unique_ptr<RouterExecStage>( 135 OperationContext*, executor::TaskExecutor*, ClusterClientCursorParams*)> 136 createCustomCursorSource; 137 138 // Whether the client indicated that it is willing to receive partial results in the case of an 139 // unreachable host. 140 bool isAllowPartialResults = false; 141 }; 142 143 } // mongo 144