diff options
author | Ian Boros <puppyofkosh@gmail.com> | 2019-07-02 14:29:56 -0400 |
---|---|---|
committer | Ian Boros <ian.boros@mongodb.com> | 2019-07-26 11:21:22 -0400 |
commit | 7a4fce6cfde41529c447417318e9c79ae42e92f0 (patch) | |
tree | 09736fa5113dc1a20781a8522625af48685cf8a1 | |
parent | eaa3578e9f2602e82ac23599bacf6bba6800a26e (diff) | |
download | mongo-7a4fce6cfde41529c447417318e9c79ae42e92f0.tar.gz |
SERVER-40110 don't call OpContext::checkForInterrupt() off-thread
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 { |