Skip to content

Commit b00584b

Browse files
committed
PYTHON-1353 Kill cursors synchronously in CommandCursor.close.
1 parent 7051faa commit b00584b

File tree

4 files changed

+28
-15
lines changed

4 files changed

+28
-15
lines changed

pymongo/command_cursor.py

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -48,20 +48,24 @@ def __del__(self):
4848
if self.__id and not self.__killed:
4949
self.__die()
5050

51-
def __die(self):
51+
def __die(self, synchronous=False):
5252
"""Closes this cursor.
5353
"""
5454
if self.__id and not self.__killed:
55-
self.__collection.database.client.close_cursor(
56-
self.__id, _CursorAddress(self.__address, self.__ns))
55+
address = _CursorAddress(
56+
self.__address, self.__collection.full_name)
57+
if synchronous:
58+
self.__collection.database.client._close_cursor_now(
59+
self.__id, address)
60+
else:
61+
self.__collection.database.client.close_cursor(
62+
self.__id, address)
5763
self.__killed = True
5864

5965
def close(self):
60-
"""Explicitly close / kill this cursor. Required for PyPy, Jython and
61-
other Python implementations that don't use reference counting
62-
garbage collection.
66+
"""Explicitly close / kill this cursor.
6367
"""
64-
self.__die()
68+
self.__die(True)
6569

6670
def batch_size(self, batch_size):
6771
"""Limits the number of documents returned in one batch. Each batch
@@ -242,4 +246,4 @@ def __enter__(self):
242246
return self
243247

244248
def __exit__(self, exc_type, exc_val, exc_tb):
245-
self.__die()
249+
self.close()

pymongo/cursor.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -294,9 +294,7 @@ def __die(self, synchronous=False):
294294
self.__killed = True
295295

296296
def close(self):
297-
"""Explicitly close / kill this cursor. Required for PyPy, Jython and
298-
other Python implementations that don't use reference counting
299-
garbage collection.
297+
"""Explicitly close / kill this cursor.
300298
"""
301299
self.__die(True)
302300

test/test_client.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -534,6 +534,10 @@ def test_close_kills_cursors(self):
534534
cursor = coll.find().batch_size(10)
535535
self.assertTrue(bool(next(cursor)))
536536
self.assertLess(cursor.retrieved, docs_inserted)
537+
538+
# Open a command cursor and leave it open on the server.
539+
cursor = coll.aggregate([], batchSize=10)
540+
self.assertTrue(bool(next(cursor)))
537541
del cursor
538542
# Required for PyPy, Jython and other Python implementations that
539543
# don't use reference counting garbage collection.

test/test_cursor.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1302,17 +1302,24 @@ def test_close_kills_cursor_synchronously(self):
13021302

13031303
results.clear()
13041304

1305-
# Close the cursor while it's still open on the server.
1305+
# Close a cursor while it's still open on the server.
13061306
cursor = coll.find().batch_size(10)
13071307
self.assertTrue(bool(next(cursor)))
13081308
self.assertLess(cursor.retrieved, docs_inserted)
13091309
cursor.close()
13101310

1311-
# Test that the cursor was closed.
1312-
self.assertEqual(1, len(results["started"]))
1311+
# Close a command cursor while it's still open on the server.
1312+
cursor = coll.aggregate([], batchSize=10)
1313+
self.assertTrue(bool(next(cursor)))
1314+
cursor.close()
1315+
1316+
# Test that both cursors were closed.
1317+
self.assertEqual(2, len(results["started"]))
13131318
self.assertEqual("killCursors", results["started"][0].command_name)
1314-
self.assertEqual(1, len(results["succeeded"]))
1319+
self.assertEqual("killCursors", results["started"][1].command_name)
1320+
self.assertEqual(2, len(results["succeeded"]))
13151321
self.assertEqual("killCursors", results["succeeded"][0].command_name)
1322+
self.assertEqual("killCursors", results["succeeded"][1].command_name)
13161323

13171324

13181325
if __name__ == "__main__":

0 commit comments

Comments
 (0)