Skip to content

PYTHON-1301/PYTHON-1302/PYTHON-1588 Remove deprecated cursor manager APIs #550

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jan 16, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions doc/api/pymongo/cursor_manager.rst

This file was deleted.

1 change: 0 additions & 1 deletion doc/api/pymongo/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ Sub-modules:
collection
command_cursor
cursor
cursor_manager
database
driver_info
encryption
Expand Down
3 changes: 0 additions & 3 deletions doc/api/pymongo/mongo_client.rst
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,3 @@
.. automethod:: get_database
.. automethod:: server_info
.. automethod:: watch
.. automethod:: close_cursor
.. automethod:: kill_cursors
.. automethod:: set_cursor_manager
6 changes: 6 additions & 0 deletions doc/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ Breaking Changes in 4.0
- Removed :meth:`pymongo.mongo_client.MongoClient.database_names`.
- Removed :meth:`pymongo.database.Database.collection_names`.
- Removed :meth:`pymongo.collection.Collection.parallel_scan`.
- Removed :meth:`pymongo.mongo_client.MongoClient.close_cursor`. Use
:meth:`pymongo.cursor.Cursor.close` instead.
- Removed :meth:`pymongo.mongo_client.MongoClient.kill_cursors`.
- Removed :class:`pymongo.cursor_manager.CursorManager` and
:mod:`pymongo.cursor_manager`.
- Removed :meth:`pymongo.mongo_client.MongoClient.set_cursor_manager`.
- Removed :mod:`pymongo.thread_util`.
- Removed :class:`~pymongo.mongo_replica_set_client.MongoReplicaSetClient`.

Expand Down
18 changes: 17 additions & 1 deletion doc/migrate-to-pymongo4.rst
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,23 @@ can be changed to this::
Removed features with no migration path
---------------------------------------

cursor_manager support is removed
.................................

Removed :class:`pymongo.cursor_manager.CursorManager`,
:mod:`pymongo.cursor_manager`, and
:meth:`pymongo.mongo_client.MongoClient.set_cursor_manager`.

MongoClient.close_cursor is removed
...................................

Removed :meth:`pymongo.mongo_client.MongoClient.close_cursor` and
:meth:`pymongo.mongo_client.MongoClient.kill_cursors`. Instead, close cursors
with :meth:`pymongo.cursor.Cursor.close` or
:meth:`pymongo.command_cursor.CommandCursor.close`.

.. _killCursors command: https://docs.mongodb.com/manual/reference/command/killCursors/

Database.eval, Database.system_js, and SystemJS are removed
...........................................................

Expand All @@ -157,7 +174,6 @@ can be changed to this::
>>> from bson.code import Code
>>> result = database.command('eval', Code('function (x) {return x;}'), args=[3]).get('retval')


Collection.parallel_scan is removed
...................................

Expand Down
3 changes: 2 additions & 1 deletion pymongo/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@
# Frequency to call ismaster on servers, in seconds.
HEARTBEAT_FREQUENCY = 10

# Frequency to process kill-cursors, in seconds. See MongoClient.close_cursor.
# Frequency to clean up unclosed cursors, in seconds.
# See MongoClient._process_kill_cursors.
KILL_CURSOR_FREQUENCY = 1

# Frequency to process events queue, in seconds.
Expand Down
4 changes: 0 additions & 4 deletions pymongo/cursor.py
Original file line number Diff line number Diff line change
Expand Up @@ -1171,10 +1171,6 @@ def alive(self):
def cursor_id(self):
"""Returns the id of the cursor

Useful if you need to manage cursor ids and want to handle killing
cursors manually using
:meth:`~pymongo.mongo_client.MongoClient.kill_cursors`

.. versionadded:: 2.2
"""
return self.__id
Expand Down
65 changes: 0 additions & 65 deletions pymongo/cursor_manager.py

This file was deleted.

119 changes: 8 additions & 111 deletions pymongo/mongo_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@
from pymongo.change_stream import ClusterChangeStream
from pymongo.client_options import ClientOptions
from pymongo.command_cursor import CommandCursor
from pymongo.cursor_manager import CursorManager
from pymongo.errors import (AutoReconnect,
BulkWriteError,
ConfigurationError,
Expand Down Expand Up @@ -704,7 +703,6 @@ def __init__(

self.__default_database_name = dbase
self.__lock = threading.Lock()
self.__cursor_manager = None
self.__kill_cursors_queue = []

self._event_listeners = options.pool_options.event_listeners
Expand Down Expand Up @@ -1209,35 +1207,6 @@ def close(self):
# TODO: PYTHON-1921 Encrypted MongoClients cannot be re-opened.
self._encrypter.close()

def set_cursor_manager(self, manager_class):
"""DEPRECATED - Set this client's cursor manager.

Raises :class:`TypeError` if `manager_class` is not a subclass of
:class:`~pymongo.cursor_manager.CursorManager`. A cursor manager
handles closing cursors. Different managers can implement different
policies in terms of when to actually kill a cursor that has
been closed.

:Parameters:
- `manager_class`: cursor manager to use

.. versionchanged:: 3.3
Deprecated, for real this time.

.. versionchanged:: 3.0
Undeprecated.
"""
warnings.warn(
"set_cursor_manager is Deprecated",
DeprecationWarning,
stacklevel=2)
manager = manager_class(self)
if not isinstance(manager, CursorManager):
raise TypeError("manager_class must be a subclass of "
"CursorManager")

self.__cursor_manager = manager

def _get_topology(self):
"""Get the internal :class:`~pymongo.topology.Topology` object.

Expand Down Expand Up @@ -1580,101 +1549,29 @@ def __getitem__(self, name):
"""
return database.Database(self, name)

def close_cursor(self, cursor_id, address=None):
"""DEPRECATED - Send a kill cursors message soon with the given id.

Raises :class:`TypeError` if `cursor_id` is not an instance of
``(int, long)``. What closing the cursor actually means
depends on this client's cursor manager.

This method may be called from a :class:`~pymongo.cursor.Cursor`
destructor during garbage collection, so it isn't safe to take a
lock or do network I/O. Instead, we schedule the cursor to be closed
soon on a background thread.

:Parameters:
- `cursor_id`: id of cursor to close
- `address` (optional): (host, port) pair of the cursor's server.
If it is not provided, the client attempts to close the cursor on
the primary or standalone, or a mongos server.

.. versionchanged:: 3.7
Deprecated.

.. versionchanged:: 3.0
Added ``address`` parameter.
"""
warnings.warn(
"close_cursor is deprecated.",
DeprecationWarning,
stacklevel=2)
if not isinstance(cursor_id, integer_types):
raise TypeError("cursor_id must be an instance of (int, long)")

self._close_cursor(cursor_id, address)

def _close_cursor(self, cursor_id, address):
"""Send a kill cursors message with the given id.

What closing the cursor actually means depends on this client's
cursor manager. If there is none, the cursor is closed asynchronously
on a background thread.
"""
if self.__cursor_manager is not None:
self.__cursor_manager.close(cursor_id, address)
else:
self.__kill_cursors_queue.append((address, [cursor_id]))
self.__kill_cursors_queue.append((address, [cursor_id]))

def _close_cursor_now(self, cursor_id, address=None, session=None):
"""Send a kill cursors message with the given id.

What closing the cursor actually means depends on this client's
cursor manager. If there is none, the cursor is closed synchronously
on the current thread.
The cursor is closed synchronously on the current thread.
"""
if not isinstance(cursor_id, integer_types):
raise TypeError("cursor_id must be an instance of (int, long)")

if self.__cursor_manager is not None:
self.__cursor_manager.close(cursor_id, address)
else:
try:
self._kill_cursors(
[cursor_id], address, self._get_topology(), session)
except PyMongoError:
# Make another attempt to kill the cursor later.
self.__kill_cursors_queue.append((address, [cursor_id]))

def kill_cursors(self, cursor_ids, address=None):
"""DEPRECATED - Send a kill cursors message soon with the given ids.

Raises :class:`TypeError` if `cursor_ids` is not an instance of
``list``.

:Parameters:
- `cursor_ids`: list of cursor ids to kill
- `address` (optional): (host, port) pair of the cursor's server.
If it is not provided, the client attempts to close the cursor on
the primary or standalone, or a mongos server.

.. versionchanged:: 3.3
Deprecated.

.. versionchanged:: 3.0
Now accepts an `address` argument. Schedules the cursors to be
closed on a background thread instead of sending the message
immediately.
"""
warnings.warn(
"kill_cursors is deprecated.",
DeprecationWarning,
stacklevel=2)

if not isinstance(cursor_ids, list):
raise TypeError("cursor_ids must be a list")

# "Atomic", needs no lock.
self.__kill_cursors_queue.append((address, cursor_ids))
try:
self._kill_cursors(
[cursor_id], address, self._get_topology(), session)
except PyMongoError:
# Make another attempt to kill the cursor later.
self.__kill_cursors_queue.append((address, [cursor_id]))

def _kill_cursors(self, cursor_ids, address, topology, session):
"""Send a kill cursors message with the given ids."""
Expand Down
Loading