Skip to content

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

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 1 commit into from
Jan 15, 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
3 changes: 0 additions & 3 deletions doc/api/pymongo/mongo_client.rst
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,3 @@
.. automethod:: close_cursor
.. automethod:: kill_cursors
.. automethod:: set_cursor_manager
.. autoattribute:: is_locked
.. automethod:: fsync
.. automethod:: unlock
3 changes: 3 additions & 0 deletions doc/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
46 changes: 46 additions & 0 deletions doc/migrate-to-pymongo4.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
---------------------------------------

Expand Down
116 changes: 0 additions & 116 deletions pymongo/mongo_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -2104,122 +2104,6 @@ def _database_default_options(self, name):
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

Expand Down
38 changes: 0 additions & 38 deletions test/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -1148,44 +1148,6 @@ def test_ipv6(self):
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")
Expand Down
26 changes: 0 additions & 26 deletions test/test_monitoring.py
Original file line number Diff line number Diff line change
Expand Up @@ -1336,32 +1336,6 @@ def test_first_batch_helper(self):
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

Expand Down
16 changes: 0 additions & 16 deletions test/test_session.py
Original file line number Diff line number Diff line change
Expand Up @@ -230,28 +230,12 @@ def test_end_sessions(self):
@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):
Expand Down