Skip to content

Commit 34c2e2c

Browse files
committed
When the limit is reached after the initial batch of results of a FindOperation, use the same connection that was used for the initial OP_QUERY to execute the OP_KILL_CURSOR. This will ensure that a thread never attempts to checkout more than one connection at a time.
JAVA-1882
1 parent 65d5471 commit 34c2e2c

File tree

3 files changed

+18
-4
lines changed

3 files changed

+18
-4
lines changed

driver-core/src/main/com/mongodb/operation/FindOperation.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,7 @@ public BatchCursor<T> call(final ConnectionSource source, final Connection conne
406406
isPartial(),
407407
isOplogReplay(),
408408
decoder);
409-
return new QueryBatchCursor<T>(queryResult, limit, batchSize, decoder, source);
409+
return new QueryBatchCursor<T>(queryResult, limit, batchSize, decoder, source, connection);
410410
}
411411
});
412412
}

driver-core/src/main/com/mongodb/operation/QueryBatchCursor.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,11 @@ class QueryBatchCursor<T> implements BatchCursor<T> {
5050

5151
QueryBatchCursor(final QueryResult<T> firstQueryResult, final int limit, final int batchSize,
5252
final Decoder<T> decoder, final ConnectionSource connectionSource) {
53+
this(firstQueryResult, limit, batchSize, decoder, connectionSource, null);
54+
}
55+
56+
QueryBatchCursor(final QueryResult<T> firstQueryResult, final int limit, final int batchSize,
57+
final Decoder<T> decoder, final ConnectionSource connectionSource, final Connection connection) {
5358
this.namespace = firstQueryResult.getNamespace();
5459
this.limit = limit;
5560
this.batchSize = batchSize;
@@ -65,7 +70,8 @@ class QueryBatchCursor<T> implements BatchCursor<T> {
6570

6671
initFromQueryResult(firstQueryResult);
6772
if (limitReached()) {
68-
killCursor();
73+
notNull("connection", connection);
74+
killCursor(connection);
6975
}
7076
}
7177

driver-core/src/test/functional/com/mongodb/operation/QueryBatchCursorSpecification.groovy

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,12 +116,16 @@ class QueryBatchCursorSpecification extends OperationFunctionalSpecification {
116116
def 'test limit exhaustion'() {
117117
given:
118118
def firstBatch = executeQuery(2)
119+
def connection = connectionSource.getConnection()
119120

120121
when:
121-
cursor = new QueryBatchCursor<Document>(firstBatch, 5, 2, new DocumentCodec(), connectionSource)
122+
cursor = new QueryBatchCursor<Document>(firstBatch, 5, 2, new DocumentCodec(), connectionSource, connection)
122123

123124
then:
124125
cursor.iterator().sum { it.size } == 5
126+
127+
cleanup:
128+
connection?.release()
125129
}
126130

127131
def 'test remove'() {
@@ -241,8 +245,9 @@ class QueryBatchCursorSpecification extends OperationFunctionalSpecification {
241245
def 'should kill cursor if limit is reached on initial query'() throws InterruptedException {
242246
given:
243247
def firstBatch = executeQuery(5)
248+
def connection = connectionSource.getConnection()
244249

245-
cursor = new QueryBatchCursor<Document>(firstBatch, 5, 0, new DocumentCodec(), connectionSource)
250+
cursor = new QueryBatchCursor<Document>(firstBatch, 5, 0, new DocumentCodec(), connectionSource, connection)
246251

247252
ServerCursor serverCursor = cursor.getServerCursor()
248253
Thread.sleep(1000) //Note: waiting for some time for killCursor operation to be performed on a server.
@@ -252,6 +257,9 @@ class QueryBatchCursorSpecification extends OperationFunctionalSpecification {
252257

253258
then:
254259
thrown(MongoCursorNotFoundException)
260+
261+
cleanup:
262+
connection?.release()
255263
}
256264

257265
@IgnoreIf({ isSharded() && !serverVersionAtLeast([2, 4, 0]) })

0 commit comments

Comments
 (0)