-
Type: Task
-
Resolution: Fixed
-
Priority: Unknown
-
Affects Version/s: None
-
Component/s: None
Use Case
As a... Driver Engineer
I want... to implement the CSOT specification for cursors
So that... we can be spec compliant
User Impact
- N/A, new behaviour
Dependencies
- Depends on
NODE-5682
Unknowns
- questions that need to be answered to determine implementation
Acceptance Criteria
Implementation Requirements
- Update the following cursor-creating commands to support timeoutMode
- Collection.find
- Collection.findOne
- Collection.watch
- Collection.listIndexes
- Db.aggregate
- Db.watch
- Db.listCollections
- Update the following classes
- AbstractCursor
- add timeoutMode field
- check timeoutMode in constructor and throw if it has been set but timeoutMS has not
- update AbstractCursor.next to take timeoutContext into account based on the configured timeoutMode
- update AbstractCursor.close to refresh timeout for killCursors command.
- update AbstractCursor.close to take a timeoutMS option that overrides the previously configured timeoutMS
- FindCursor
- Update to set timeoutMode to CURSOR_LIFETIME by default (depending on whether or not the cursor is tailable)
- ListIndexesCursor
- Update to set timeoutMode to CURSOR_LIFETIME by default
- AggregationCursor
- Update to set timeoutMode to CURSOR_LIFETIME by default
- ChangeStreamCursor
- Update to set timeoutMode to CURSOR_LIFETIME. Throw if attempt is made to set timeoutMode to ITERATION
- ListCollectionsCursor
- Update to set timeoutMode to CURSOR_LIFETIME by default
- RunCommandCursor
- Update to set timeoutMode based on whether or not cursor is tailable
- AbstractCursor
Testing Requirements
Unit tests
- ChangeStreamCursor
- Given that timeoutMS is defined, should have timeoutMode of ITERATION
- FindCursor, ListIndexesCursor, ListCollectionsCursor/AggregationCursor/RunCommandCursor constructors
- Given tailable: false, timeoutMode should default to CURSOR_LIFETIME
- Given tailable: true, timeoutMode should default to ITERATION
- AggregationCursor constructor
- given timeoutMode of ITERATION and has a $out or $merge stage, should throw a MongoAPIError
- AggregationCursor.addStage
- given that timeoutMode: ITERATION , when $out or $merge stage is added, throws a MongoAPIError
Integration tests
Non-Tailable Cursors - CURSOR_LIFETIME mode
- Given a non-tailable cursor in CURSOR_LIFETIME mode, when executing next calls, DO NOT append a maxTimeMS field to getMore commands being sent to the server
- Given a non-tailable cursor in CURSOR_LIFETIME mode, when making a next call, if there are documents remaining from a previously retrieved batch, the next method MUST return them even if the timeout has expired.
- Given a non-tailable cursor in CURSOR_LIFETIME mode, when making a next call, iff a getMore is required and the timeout has expired, throw a MongoOperationTimeoutError
Non-Tailable Cursors - ITERATION mode
Given a non-tailable cursor in ITERATION mode, when executing an aggregate with a $out or $merge stage, throw a MongoInvalidArgumentError- Given a non-tailable cursor in ITERATION mode, when executing any valid operation, the configured timeoutMS MUST apply to the initial operation execution. The timeout MUST be refreshed for any getMores
- Given a non-tailable cursor in ITERATION mode, when execution any valid operation, DO NOT append a maxTimeMS field to original command or subsequent getMores
Tailable non-awaitData cursors
- Given a tailable non-awaitData Cursor, timeoutMS must be applied separately to the original operation and all subsequent next calls
- Given a tailable non-awaitData cursor, maxTimeMS MUST NOT be applied to any commands
Tailable awaitData cursors
- Given a tailable awaitData Cursor, timeoutMS must be applied separately to the original operation and all subsequent next calls
- Given a tailable awaitData Cursor, timeoutMS must not be used to derive a maxTimeMS value for getMore commands
- Given a tailable awaitData Cursor, if timeoutMS is set to a non-zero value and maxAwaitTimeMS is set and greater than or equal to timeoutMS, throw an error
- Given a tailable awaitData Cursor, if maxAwaitTimeMS is set, this value MUST be used as the maxTimeMS field on getMore commands
- Enable the following spec tests
- Implement the following prose tests
- Copy all driver benchmarks and enable CSOT. Record relative performance of tests without CSOT behaviour enabled and those with CSOT behaviour enabled. File follow up if significant performance degradations are observerd
Documentation Requirements
- Punting to NODE-5688
- In particular, note that CURSOR_LIFETIME mode must be limited to short-lived cursors due to potential to hang for entirety of timeoutMS
Follow Up Requirements
- May need to file perf follow-ups depending on the results obtained when comparing performance of tests with CSOT enabled versus previously existing benchmarks.