PYTHON-2165 Deprecate MongoClient is_locked, fsync, and unlock helpers (#459)

This commit is contained in:
Shane Harvey 2020-07-08 17:18:02 -07:00 committed by GitHub
parent 426f5fdef7
commit e3f40c30ad
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 96 additions and 22 deletions

View File

@ -34,7 +34,6 @@
.. autoattribute:: read_preference
.. autoattribute:: write_concern
.. autoattribute:: read_concern
.. autoattribute:: is_locked
.. automethod:: start_session
.. automethod:: list_databases
.. automethod:: list_database_names
@ -43,9 +42,10 @@
.. automethod:: get_default_database
.. automethod:: get_database
.. automethod:: server_info
.. automethod:: watch
.. automethod:: close_cursor
.. automethod:: kill_cursors
.. automethod:: set_cursor_manager
.. automethod:: watch
.. autoattribute:: is_locked
.. automethod:: fsync
.. automethod:: unlock

View File

@ -46,6 +46,12 @@ Highlights include:
:class:`~pymongo.read_preferences.SecondaryPreferred`,
:class:`~pymongo.read_preferences.Nearest` to support disabling
(or explicitly enabling) hedged reads in MongoDB 4.4+.
- Fixed a bug in change streams that could cause PyMongo to miss some change
documents when resuming a stream that was started without a resume token and
whose first batch did not contain any change documents.
Deprecations:
- Deprecated the ``oplog_replay`` parameter to
:meth:`pymongo.collection.Collection.find`. Starting in MongoDB 4.4, the
server optimizes queries against the oplog collection without requiring
@ -53,9 +59,15 @@ Highlights include:
- Deprecated :meth:`pymongo.collection.Collection.reindex`. Use
:meth:`~pymongo.database.Database.command` to run the ``reIndex`` command
instead.
- Fixed a bug in change streams that could cause PyMongo to miss some change
documents when resuming a stream that was started without a resume token and
whose first batch did not contain any change documents.
- Deprecated :meth:`pymongo.mongo_client.MongoClient.fsync`. Use
:meth:`~pymongo.database.Database.command` to run the ``fsync`` command
instead.
- Deprecated :meth:`pymongo.mongo_client.MongoClient.unlock`. Use
:meth:`~pymongo.database.Database.command` to run the ``fsyncUnlock`` command
instead. See the documentation for more information.
- Deprecated :attr:`pymongo.mongo_client.MongoClient.is_locked`. Use
:meth:`~pymongo.database.Database.command` to run the ``currentOp`` command
instead. See the documentation for more information.
Unavoidable breaking changes:

View File

@ -2083,15 +2083,33 @@ class MongoClient(common.BaseObject):
@property
def is_locked(self):
"""Is this server locked? While locked, all write operations
are blocked, although read operations may still be allowed.
"""**DEPRECATED**: Is this server locked? While locked, all write
operations are blocked, although read operations may still be allowed.
Use :meth:`unlock` to unlock.
Deprecated. Users of MongoDB version 3.2 or newer can run the
`currentOp command`_ directly with
:meth:`~pymongo.database.Database.command`::
is_locked = client.admin.command('currentOp').get('fsyncLock')
Users of MongoDB version 2.6 and 3.0 can query the "inprog" virtual
collection::
is_locked = client.admin["$cmd.sys.inprog"].find_one().get('fsyncLock')
.. versionchanged:: 3.11
Deprecated.
.. _currentOp command: https://docs.mongodb.com/manual/reference/command/currentOp/
"""
warnings.warn("is_locked is deprecated. See the documentation for "
"more information.", DeprecationWarning, stacklevel=2)
ops = self._database_default_options('admin')._current_op()
return bool(ops.get('fsyncLock', 0))
def fsync(self, **kwargs):
"""Flush all pending writes to datafiles.
"""**DEPRECATED**: Flush all pending writes to datafiles.
Optional parameters can be passed as keyword arguments:
- `lock`: If True lock the server to disallow writes.
@ -2106,6 +2124,14 @@ class MongoClient(common.BaseObject):
options = {'async': True}
client.fsync(**options)
Deprecated. Run the `fsync command`_ directly with
:meth:`~pymongo.database.Database.command` instead. For example::
client.admin.command('fsync', lock=True)
.. versionchanged:: 3.11
Deprecated.
.. versionchanged:: 3.6
Added ``session`` parameter.
@ -2114,20 +2140,46 @@ class MongoClient(common.BaseObject):
.. warning:: MongoDB does not support the `async` option
on Windows and will raise an exception on that
platform.
.. _fsync command: https://docs.mongodb.com/manual/reference/command/fsync/
"""
warnings.warn("fsync is deprecated. Use "
"client.admin.command('fsync') instead.",
DeprecationWarning, stacklevel=2)
self.admin.command("fsync",
read_preference=ReadPreference.PRIMARY, **kwargs)
def unlock(self, session=None):
"""Unlock a previously locked server.
"""**DEPRECATED**: Unlock a previously locked server.
:Parameters:
- `session` (optional): a
:class:`~pymongo.client_session.ClientSession`.
Deprecated. Users of MongoDB version 3.2 or newer can run the
`fsyncUnlock command`_ directly with
:meth:`~pymongo.database.Database.command`::
client.admin.command('fsyncUnlock')
Users of MongoDB version 2.6 and 3.0 can query the "unlock" virtual
collection::
client.admin["$cmd.sys.unlock"].find_one()
.. versionchanged:: 3.11
Deprecated.
.. versionchanged:: 3.6
Added ``session`` parameter.
.. _fsyncUnlock command: https://docs.mongodb.com/manual/reference/command/fsyncUnlock/
"""
warnings.warn("unlock is deprecated. Use "
"client.admin.command('fsyncUnlock') instead. For "
"MongoDB 2.6 and 3.0, see the documentation for "
"more information.",
DeprecationWarning, stacklevel=2)
cmd = SON([("fsyncUnlock", 1)])
with self._socket_for_writes(session) as sock_info:
if sock_info.max_wire_version >= 4:

View File

@ -1120,6 +1120,7 @@ class TestClient(IntegrationTest):
self.assertTrue("pymongo_test" in dbs)
self.assertTrue("pymongo_test_bernie" in dbs)
@ignore_deprecations
@client_context.require_no_mongos
def test_fsync_lock_unlock(self):
if server_is_master_with_slave(client_context.client):
@ -1143,13 +1144,19 @@ class TestClient(IntegrationTest):
time.sleep(1)
self.assertFalse(locked)
def test_is_locked_does_not_raise_warning(self):
client = rs_or_single_client()
with warnings.catch_warnings(record=True) as ctx:
warnings.simplefilter("always")
_ = client.is_locked
self.assertFalse(
any(issubclass(w.category, DeprecationWarning) for w in ctx))
def test_deprecated_methods(self):
with warnings.catch_warnings():
warnings.simplefilter("error", DeprecationWarning)
with self.assertRaisesRegex(DeprecationWarning,
'is_locked is deprecated'):
_ = self.client.is_locked
if not client_context.is_mongos:
with self.assertRaisesRegex(DeprecationWarning,
'fsync is deprecated'):
self.client.fsync(lock=True)
with self.assertRaisesRegex(DeprecationWarning,
'unlock is deprecated'):
self.client.unlock()
def test_contextlib(self):
client = rs_or_single_client()

View File

@ -37,6 +37,7 @@ from test import (client_context,
unittest)
from test.utils import (EventListener,
get_pool,
ignore_deprecations,
rs_or_single_client,
single_client,
wait_until)
@ -1336,12 +1337,13 @@ class TestCommandMonitoring(PyMongoTestCase):
self.assertTrue('ok' in succeeded.reply)
if not client_context.is_mongos:
self.client.fsync(lock=True)
self.listener.results.clear()
self.client.unlock()
# Wait for async unlock...
wait_until(
lambda: not self.client.is_locked, "unlock the database")
with ignore_deprecations():
self.client.fsync(lock=True)
self.listener.results.clear()
self.client.unlock()
# Wait for async unlock...
wait_until(
lambda: not self.client.is_locked, "unlock the database")
started = results['started'][0]
succeeded = results['succeeded'][0]
self.assertEqual(0, len(results['failed']))

View File

@ -227,6 +227,7 @@ class TestSession(IntegrationTest):
client.close()
self.assertEqual(len(listener.results['started']), 0)
@ignore_deprecations # fsync and unlock
def test_client(self):
client = self.client