summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Boros <puppyofkosh@gmail.com>2019-07-02 14:29:56 -0400
committerIan Boros <ian.boros@mongodb.com>2019-07-26 11:21:22 -0400
commit7a4fce6cfde41529c447417318e9c79ae42e92f0 (patch)
tree09736fa5113dc1a20781a8522625af48685cf8a1
parenteaa3578e9f2602e82ac23599bacf6bba6800a26e (diff)
downloadmongo-7a4fce6cfde41529c447417318e9c79ae42e92f0.tar.gz
SERVER-40110 don't call OpContext::checkForInterrupt() off-thread
-rw-r--r--buildscripts/resmokeconfig/suites/concurrency_sharded_with_stepdowns.yml1
-rw-r--r--buildscripts/resmokeconfig/suites/concurrency_sharded_with_stepdowns_and_balancer.yml1
-rw-r--r--jstests/concurrency/fsm_workloads/server_status_with_time_out_cursors.js72
-rw-r--r--src/mongo/s/query/cluster_cursor_manager.h9
4 files changed, 81 insertions, 2 deletions
diff --git a/buildscripts/resmokeconfig/suites/concurrency_sharded_with_stepdowns.yml b/buildscripts/resmokeconfig/suites/concurrency_sharded_with_stepdowns.yml
index 856f6f69e31..63f8d191d52 100644
--- a/buildscripts/resmokeconfig/suites/concurrency_sharded_with_stepdowns.yml
+++ b/buildscripts/resmokeconfig/suites/concurrency_sharded_with_stepdowns.yml
@@ -123,6 +123,7 @@ selector:
- jstests/concurrency/fsm_workloads/reindex_background.js
- jstests/concurrency/fsm_workloads/remove_multiple_documents.js
- jstests/concurrency/fsm_workloads/remove_where.js
+ - jstests/concurrency/fsm_workloads/server_status_with_time_out_cursors.js
- jstests/concurrency/fsm_workloads/touch_base.js
- jstests/concurrency/fsm_workloads/touch_data.js
- jstests/concurrency/fsm_workloads/touch_index.js
diff --git a/buildscripts/resmokeconfig/suites/concurrency_sharded_with_stepdowns_and_balancer.yml b/buildscripts/resmokeconfig/suites/concurrency_sharded_with_stepdowns_and_balancer.yml
index 304136f9c36..89d0553cd7d 100644
--- a/buildscripts/resmokeconfig/suites/concurrency_sharded_with_stepdowns_and_balancer.yml
+++ b/buildscripts/resmokeconfig/suites/concurrency_sharded_with_stepdowns_and_balancer.yml
@@ -125,6 +125,7 @@ selector:
- jstests/concurrency/fsm_workloads/reindex.js
- jstests/concurrency/fsm_workloads/reindex_background.js
- jstests/concurrency/fsm_workloads/remove_multiple_documents.js
+ - jstests/concurrency/fsm_workloads/server_status_with_time_out_cursors.js
- jstests/concurrency/fsm_workloads/touch_base.js
- jstests/concurrency/fsm_workloads/touch_data.js
- jstests/concurrency/fsm_workloads/touch_index.js
diff --git a/jstests/concurrency/fsm_workloads/server_status_with_time_out_cursors.js b/jstests/concurrency/fsm_workloads/server_status_with_time_out_cursors.js
new file mode 100644
index 00000000000..d9249534e9a
--- /dev/null
+++ b/jstests/concurrency/fsm_workloads/server_status_with_time_out_cursors.js
@@ -0,0 +1,72 @@
+'use strict';
+
+/**
+ * Run serverStatus() while running a large number of queries which are expected to reach maxTimeMS
+ * and time out.
+ */
+load('jstests/concurrency/fsm_workload_helpers/server_types.js'); // for isMongos
+
+var $config = (function() {
+
+ const states = {
+ /**
+ * This is a no-op, used only as a transition state.
+ */
+ init: function init(db, collName) {},
+
+ /**
+ * Runs a query on the collection with a small enough batchSize to leave the cursor open.
+ * If the command was successful, stores the resulting cursor in 'this.cursor'.
+ */
+ query: function query(db, collName) {
+ try {
+ // Set a low maxTimeMs and small batch size so that it's likely the cursor will
+ // time out over its lifetime.
+ let curs = db[collName]
+ .find({
+ $where: function() {
+ sleep(1);
+ return true;
+ }
+ })
+ .batchSize(2)
+ .maxTimeMS(10);
+
+ const c = curs.itcount();
+ } catch (e) {
+ assert.commandFailedWithCode(e, [
+ ErrorCodes.MaxTimeMSExpired,
+ ]);
+ }
+ },
+
+ serverStatus: function serverStatus(db, collName) {
+ assert.commandWorked(db.adminCommand({serverStatus: 1}));
+ }
+ };
+
+ const transitions = {
+ init: {
+ query: 0.8,
+ serverStatus: 0.2,
+ },
+
+ query: {query: 0.8, serverStatus: 0.2},
+ serverStatus: {query: 0.5, serverStatus: 0.5},
+ };
+
+ function setup(db, collName, cluster) {
+ // Write some data.
+ assertWhenOwnColl.commandWorked(
+ db[collName].insert(Array.from({length: 100}, _ => ({a: 1}))));
+ }
+
+ return {
+ threadCount: 10,
+ iterations: 100,
+ states: states,
+ startState: 'init',
+ transitions: transitions,
+ setup: setup,
+ };
+})();
diff --git a/src/mongo/s/query/cluster_cursor_manager.h b/src/mongo/s/query/cluster_cursor_manager.h
index 0fcf0a51532..353727349b7 100644
--- a/src/mongo/s/query/cluster_cursor_manager.h
+++ b/src/mongo/s/query/cluster_cursor_manager.h
@@ -586,8 +586,13 @@ private:
bool isKillPending() const {
// A cursor is kill pending if it's checked out by an OperationContext that was
// interrupted.
- return _operationUsingCursor &&
- !_operationUsingCursor->checkForInterruptNoAssert().isOK();
+ if (!_operationUsingCursor) {
+ return false;
+ }
+
+ // Must hold the Client lock when calling isKillPending().
+ stdx::unique_lock<Client> lk(*_operationUsingCursor->getClient());
+ return _operationUsingCursor->isKillPending();
}
CursorType getCursorType() const {