PYTHON-2310 Remove MongoClient.fsync, unlock, and is_locked (#546)

This commit is contained in:
Shane Harvey 2021-01-15 11:29:23 -08:00 committed by GitHub
parent c70071df1d
commit 387bfa0bfa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 49 additions and 199 deletions

View File

@ -46,6 +46,3 @@
.. automethod:: close_cursor
.. automethod:: kill_cursors
.. automethod:: set_cursor_manager
.. autoattribute:: is_locked
.. automethod:: fsync
.. automethod:: unlock

View File

@ -18,6 +18,9 @@ Breaking Changes in 4.0
- Removed :meth:`~pymongo.database.Database.eval`,
:data:`~pymongo.database.Database.system_js` and
:class:`~pymongo.database.SystemJS`.
- Removed :meth:`pymongo.mongo_client.MongoClient.fsync`,
:meth:`pymongo.mongo_client.MongoClient.unlock`, and
:attr:`pymongo.mongo_client.MongoClient.is_locked`.
- Removed :mod:`~pymongo.thread_util`.
Notable improvements

View File

@ -50,6 +50,52 @@ Warnings can also be changed to errors::
.. note:: Not all deprecated features raise :exc:`DeprecationWarning` when
used. See `Removed features with no migration path`_.
MongoClient
-----------
MongoClient.fsync is removed
............................
Removed :meth:`pymongo.mongo_client.MongoClient.fsync`. Run the
`fsync command`_ directly with :meth:`~pymongo.database.Database.command`
instead. For example::
client.admin.command('fsync', lock=True)
.. _fsync command: https://docs.mongodb.com/manual/reference/command/fsync/
MongoClient.unlock is removed
.............................
Removed :meth:`pymongo.mongo_client.MongoClient.unlock`. 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()
.. _fsyncUnlock command: https://docs.mongodb.com/manual/reference/command/fsyncUnlock/
MongoClient.is_locked is removed
................................
Removed :attr:`pymongo.mongo_client.MongoClient.is_locked`. 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')
.. _currentOp command: https://docs.mongodb.com/manual/reference/command/currentOp/
Removed features with no migration path
---------------------------------------

View File

@ -2104,122 +2104,6 @@ class MongoClient(common.BaseObject):
read_preference=ReadPreference.PRIMARY,
write_concern=DEFAULT_WRITE_CONCERN)
@property
def is_locked(self):
"""**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):
"""**DEPRECATED**: Flush all pending writes to datafiles.
Optional parameters can be passed as keyword arguments:
- `lock`: If True lock the server to disallow writes.
- `async`: If True don't block while synchronizing.
- `session` (optional): a
:class:`~pymongo.client_session.ClientSession`.
.. note:: Starting with Python 3.7 `async` is a reserved keyword.
The async option to the fsync command can be passed using a
dictionary instead::
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.
.. warning:: `async` and `lock` can not be used together.
.. 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):
"""**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:
try:
with self._tmp_session(session) as s:
sock_info.command(
"admin", cmd, session=s, client=self)
except OperationFailure as exc:
# Ignore "DB not locked" to replicate old behavior
if exc.code != 125:
raise
else:
message._first_batch(sock_info, "admin", "$cmd.sys.unlock",
{}, -1, True, self.codec_options,
ReadPreference.PRIMARY, cmd,
self._event_listeners)
def __enter__(self):
return self

View File

@ -1148,44 +1148,6 @@ 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):
raise SkipTest('SERVER-7714')
self.assertFalse(self.client.is_locked)
# async flushing not supported on windows...
if sys.platform not in ('cygwin', 'win32'):
# Work around async becoming a reserved keyword in Python 3.7
opts = {'async': True}
self.client.fsync(**opts)
self.assertFalse(self.client.is_locked)
self.client.fsync(lock=True)
self.assertTrue(self.client.is_locked)
locked = True
self.client.unlock()
for _ in range(5):
locked = self.client.is_locked
if not locked:
break
time.sleep(1)
self.assertFalse(locked)
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()
client.pymongo_test.drop_collection("test")

View File

@ -1336,32 +1336,6 @@ class TestCommandMonitoring(PyMongoTestCase):
self.assertTrue('inprog' in succeeded.reply)
self.assertTrue('ok' in succeeded.reply)
if not client_context.is_mongos:
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']))
self.assertIsInstance(started, monitoring.CommandStartedEvent)
expected = {'fsyncUnlock': 1}
self.assertEqualCommand(expected, started.command)
self.assertEqual('admin', started.database_name)
self.assertEqual('fsyncUnlock', started.command_name)
self.assertIsInstance(started.request_id, int)
self.assertEqual(self.client.address, started.connection_id)
self.assertIsInstance(succeeded, monitoring.CommandSucceededEvent)
self.assertIsInstance(succeeded.duration_micros, int)
self.assertEqual(started.command_name, succeeded.command_name)
self.assertEqual(started.request_id, succeeded.request_id)
self.assertEqual(started.connection_id, succeeded.connection_id)
self.assertTrue('info' in succeeded.reply)
self.assertTrue('ok' in succeeded.reply)
def test_sensitive_commands(self):
listeners = self.client._event_listeners

View File

@ -230,28 +230,12 @@ class TestSession(IntegrationTest):
@ignore_deprecations # fsync and unlock
def test_client(self):
client = self.client
# Make sure if the test fails we unlock the server.
def unlock():
try:
client.unlock()
except OperationFailure:
pass
self.addCleanup(unlock)
ops = [
(client.server_info, [], {}),
(client.database_names, [], {}),
(client.drop_database, ['pymongo_test'], {}),
]
if not client_context.is_mongos:
ops.extend([
(client.fsync, [], {'lock': True}),
(client.unlock, [], {}),
])
self._test_ops(client, *ops)
def test_database(self):