[JAVA-4183] Calling cursor.next() and cursor.close() concurrently in Load Balanced mode uses the same connection simultaneously Created: 01/Jun/21 Updated: 28/Oct/23 Resolved: 03/Aug/21 |
|
| Status: | Closed |
| Project: | Java Driver |
| Component/s: | Connection Management |
| Affects Version/s: | 4.3.0 |
| Fix Version/s: | 4.3.1 |
| Type: | Bug | Priority: | Major - P3 |
| Reporter: | Backlog - Core Eng Program Management Team | Assignee: | Valentin Kavalenka |
| Resolution: | Fixed | Votes: | 0 |
| Labels: | spec-compliance | ||
| Remaining Estimate: | Not Specified | ||
| Time Spent: | Not Specified | ||
| Original Estimate: | Not Specified | ||
| Issue Links: |
|
||||||||||||
| Quarter: | FY22Q2 | ||||||||||||
| Documentation Changes: | Not Needed | ||||||||||||
| Description |
|
DRIVERS Ticket Description
Script Target - If you can read this text, the script has failed
|
| Comments |
| Comment by Githook User [ 03/Aug/21 ] |
|
Author: {'name': 'Valentin Kovalenko', 'email': 'valentin.kovalenko@mongodb.com', 'username': 'stIncMale'}Message: Support calling `QueryBatchCursor.close` concurrently with other `QueryBatchCursor` methods (#765)
|
| Comment by Githook User [ 30/Jul/21 ] |
|
Author: {'name': 'Valentin Kovalenko', 'email': 'valentin.kovalenko@mongodb.com', 'username': 'stIncMale'}Message: Support calling `QueryBatchCursor.close` concurrently with other `QueryBatchCursor` methods (#765)
|
| Comment by Valentin Kavalenka [ 19/Jul/21 ] |
Java driver cursor types hierarchy
AnalysisWe can see that only QueryBatchCursor and AsyncQueryBatchCursor implement the cursor logic, while all other classes are wrappers. AsyncQueryBatchCursor supported concurrent next and close operations even before the support for LB was implemented, and as far a I can tell, that is now supported even for LB mode: killCursorOnClose uses the pinnedConnection and is executed after the concurrent getMore returns, even if it returns with no results. This way users indeed can call close to cancel next if it spins doing getMore. However, the driver does not cancel getMore, and this operation is blocked until either results are available or maxTimeMS is elapsed (see AggregatePublisher.maxAwaitTime, FindPublisher.maxAwaitTime, ChangeStreamPublisher.maxAwaitTime. QueryBatchCursor does not have the same mechanism, most likely because AggregateResponseBatchCursor is documented as @NotThreadSafe. However, the closed field is marked as volatile and before the LB changes the close method has been getting a new connection to killCursor, which strongly suggests that we allowed calling close concurrently with next to cancel it. Thus, QueryBatchCursor indeed has the bug described in this ticket. A user has access to QueryBatchCursor via MongoCursor. I suppose for asynchronous API (AsyncQueryBatchCursor.close) the close methods is called as a result of calling Subscription.cancel. Next steps
|