summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Boros <ian.boros@mongodb.com>2019-09-09 16:41:22 +0000
committerevergreen <evergreen@mongodb.com>2019-09-09 16:41:22 +0000
commitf2492afb1c5a1c50406890791d5f22ea0ae10be7 (patch)
tree72a8df9359644d983ca08bc469346c63d997d3a8
parente94563212223a8e4b341d861e3284236fe7a83e0 (diff)
downloadmongo-f2492afb1c5a1c50406890791d5f22ea0ae10be7.tar.gz
SERVER-40110 don't call OpContext::checkForInterrupt() off-thread
This commit also includes a modification to the test done under SERVER-43156.
-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.js74
-rw-r--r--src/mongo/s/query/cluster_cursor_manager.h9
4 files changed, 83 insertions, 2 deletions
diff --git a/buildscripts/resmokeconfig/suites/concurrency_sharded_with_stepdowns.yml b/buildscripts/resmokeconfig/suites/concurrency_sharded_with_stepdowns.yml
index 447835873d0..e9cb1438105 100644
--- a/buildscripts/resmokeconfig/suites/concurrency_sharded_with_stepdowns.yml
+++ b/buildscripts/resmokeconfig/suites/concurrency_sharded_with_stepdowns.yml
@@ -137,6 +137,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 1f3a6828d3a..3f470834855 100644
--- a/buildscripts/resmokeconfig/suites/concurrency_sharded_with_stepdowns_and_balancer.yml
+++ b/buildscripts/resmokeconfig/suites/concurrency_sharded_with_stepdowns_and_balancer.yml
@@ -143,6 +143,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..c3986995866
--- /dev/null
+++ b/jstests/concurrency/fsm_workloads/server_status_with_time_out_cursors.js
@@ -0,0 +1,74 @@
+'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,
+ ErrorCodes.NetworkInterfaceExceededTimeLimit,
+ // JS Execution interrupted.
+ ErrorCodes.Interrupted
+ ]);
+ }
+ },
+
+ 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 77fb5cb6288..57c139d941e 100644
--- a/src/mongo/s/query/cluster_cursor_manager.h
+++ b/src/mongo/s/query/cluster_cursor_manager.h
@@ -544,8 +544,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 {