summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTed Tuckman <ted.tuckman@mongodb.com>2018-09-13 13:43:53 -0400
committerTed Tuckman <ted.tuckman@mongodb.com>2018-09-18 13:15:13 -0400
commit157691ef0babb24cd1566446f5f88206f9607564 (patch)
treec4d9f1f68218f86f8418f712073d0dce830cab47
parentcd441ed71c1453993b3af4617e704fbbad3783ef (diff)
downloadmongo-157691ef0babb24cd1566446f5f88206f9607564.tar.gz
SERVER-37090 Add idleCursors to currentOp output for mongos
-rw-r--r--jstests/core/currentop_cursors.js18
-rw-r--r--src/mongo/db/pipeline/mongos_process_interface.h2
-rw-r--r--src/mongo/s/query/cluster_cursor_manager.cpp22
-rw-r--r--src/mongo/s/query/cluster_cursor_manager.h8
4 files changed, 36 insertions, 14 deletions
diff --git a/jstests/core/currentop_cursors.js b/jstests/core/currentop_cursors.js
index 4e8feffa9cc..b4e0949fac9 100644
--- a/jstests/core/currentop_cursors.js
+++ b/jstests/core/currentop_cursors.js
@@ -2,10 +2,7 @@
* Tests that an idle cursor will appear in the $currentOp output if the idleCursors option is
* set to true.
*
- * The work to make this feature available on mongos is deferred to SERVER-37004
- * and SERVER-37005. Those tickets will make the idleCursor fields available to curOp.
- * @tags: [assumes_against_mongod_not_mongos, assumes_read_concern_unchanged]
- *
+ * @tags: [assumes_read_concern_unchanged]
*/
(function() {
@@ -20,12 +17,19 @@
assert.commandWorked(db.runCommand({find: "jstests_currentop", batchSize: 2})).cursor.id;
const result = adminDB
.aggregate([
- {$currentOp: {allUsers: false, idleCursors: true}},
+ {$currentOp: {localOps: true, allUsers: false, idleCursors: true}},
{$match: {$and: [{type: "idleCursor"}, {"cursor.cursorId": findOut}]}}
])
.toArray();
- assert.eq(result.length, 1, tojson(result));
- assert.eq(result[0].cursor.nDocsReturned, 2, tojson(result));
+ assert.eq(result.length, 1, result);
+ assert.eq(result[0].cursor.nDocsReturned, 2, result);
+ assert.eq(result[0].cursor.tailable, false, result);
+ assert.eq(result[0].cursor.awaitData, false, result);
+ assert.eq(result[0].cursor.noCursorTimeout, false, result);
+ assert.eq(result[0].cursor.ns, coll.getFullName(), result);
+ assert.eq(result[0].cursor.originatingCommand.find, "jstests_currentop", result);
+ assert.eq(result[0].cursor.originatingCommand.batchSize, 2, result);
+
const noIdle = adminDB
.aggregate([
{$currentOp: {allUsers: false, idleCursors: false}},
diff --git a/src/mongo/db/pipeline/mongos_process_interface.h b/src/mongo/db/pipeline/mongos_process_interface.h
index 05182b4116a..b16f72608bb 100644
--- a/src/mongo/db/pipeline/mongos_process_interface.h
+++ b/src/mongo/db/pipeline/mongos_process_interface.h
@@ -52,8 +52,6 @@ public:
const Document& documentKey,
boost::optional<BSONObj> readConcern) final;
- // TODO: SERVER-37090 bring mongos getIdleCursors to match mongod and pass back GenericCursors
- // with all available fields.
std::vector<GenericCursor> getIdleCursors(const boost::intrusive_ptr<ExpressionContext>& expCtx,
CurrentOpUserMode userMode) const final;
diff --git a/src/mongo/s/query/cluster_cursor_manager.cpp b/src/mongo/s/query/cluster_cursor_manager.cpp
index a521bc13000..3b1079aabb0 100644
--- a/src/mongo/s/query/cluster_cursor_manager.cpp
+++ b/src/mongo/s/query/cluster_cursor_manager.cpp
@@ -572,6 +572,21 @@ void ClusterCursorManager::appendActiveSessions(LogicalSessionIdSet* lsids) cons
}
}
+GenericCursor ClusterCursorManager::CursorEntry::cursorToGenericCursor(
+ CursorId cursorId, const NamespaceString& ns) const {
+ invariant(_cursor);
+ GenericCursor gc;
+ gc.setCursorId(cursorId);
+ gc.setNs(ns);
+ gc.setLsid(_cursor->getLsid());
+ gc.setNDocsReturned(_cursor->getNumReturnedSoFar());
+ gc.setTailable(_cursor->isTailable());
+ gc.setAwaitData(_cursor->isTailableAndAwaitData());
+ gc.setOriginatingCommand(_cursor->getOriginatingCommand());
+ gc.setNoCursorTimeout(getLifetimeType() == CursorLifetime::Immortal);
+ return gc;
+}
+
std::vector<GenericCursor> ClusterCursorManager::getIdleCursors() const {
std::vector<GenericCursor> cursors;
@@ -586,11 +601,8 @@ std::vector<GenericCursor> ClusterCursorManager::getIdleCursors() const {
continue;
}
- cursors.emplace_back();
- auto& gc = cursors.back();
- gc.setCursorId(cursorIdEntryPair.first);
- gc.setNs(nsContainerPair.first);
- gc.setLsid(entry.getLsid());
+ cursors.emplace_back(
+ entry.cursorToGenericCursor(cursorIdEntryPair.first, nsContainerPair.first));
}
}
diff --git a/src/mongo/s/query/cluster_cursor_manager.h b/src/mongo/s/query/cluster_cursor_manager.h
index 611aa306543..37c7d7478b2 100644
--- a/src/mongo/s/query/cluster_cursor_manager.h
+++ b/src/mongo/s/query/cluster_cursor_manager.h
@@ -554,6 +554,14 @@ private:
}
/**
+ * Creates a generic cursor from the cursor inside this entry. Should only be called on
+ * idle cursors. The caller must supply the cursorId and namespace because the CursorEntry
+ * does not have access to them. Cannot be called if this CursorEntry does not own an
+ * underlying ClusterClientCursor.
+ */
+ GenericCursor cursorToGenericCursor(CursorId cursorId, const NamespaceString& ns) const;
+
+ /**
* Returns the cursor owned by this CursorEntry for an operation to use. Only one operation
* may use the cursor at a time, so callers should check that getOperationUsingCursor()
* returns null before using this function. Callers may pass nullptr, but only if the