Skip to content

Commit e3f40c3

Browse files
authored
PYTHON-2165 Deprecate MongoClient is_locked, fsync, and unlock helpers (#459)
1 parent 426f5fd commit e3f40c3

File tree

6 files changed

+96
-22
lines changed

6 files changed

+96
-22
lines changed

doc/api/pymongo/mongo_client.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@
3434
.. autoattribute:: read_preference
3535
.. autoattribute:: write_concern
3636
.. autoattribute:: read_concern
37-
.. autoattribute:: is_locked
3837
.. automethod:: start_session
3938
.. automethod:: list_databases
4039
.. automethod:: list_database_names
@@ -43,9 +42,10 @@
4342
.. automethod:: get_default_database
4443
.. automethod:: get_database
4544
.. automethod:: server_info
45+
.. automethod:: watch
4646
.. automethod:: close_cursor
4747
.. automethod:: kill_cursors
4848
.. automethod:: set_cursor_manager
49-
.. automethod:: watch
49+
.. autoattribute:: is_locked
5050
.. automethod:: fsync
5151
.. automethod:: unlock

doc/changelog.rst

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,16 +46,28 @@ Highlights include:
4646
:class:`~pymongo.read_preferences.SecondaryPreferred`,
4747
:class:`~pymongo.read_preferences.Nearest` to support disabling
4848
(or explicitly enabling) hedged reads in MongoDB 4.4+.
49+
- Fixed a bug in change streams that could cause PyMongo to miss some change
50+
documents when resuming a stream that was started without a resume token and
51+
whose first batch did not contain any change documents.
52+
53+
Deprecations:
54+
4955
- Deprecated the ``oplog_replay`` parameter to
5056
:meth:`pymongo.collection.Collection.find`. Starting in MongoDB 4.4, the
5157
server optimizes queries against the oplog collection without requiring
5258
the user to set this flag.
5359
- Deprecated :meth:`pymongo.collection.Collection.reindex`. Use
5460
:meth:`~pymongo.database.Database.command` to run the ``reIndex`` command
5561
instead.
56-
- Fixed a bug in change streams that could cause PyMongo to miss some change
57-
documents when resuming a stream that was started without a resume token and
58-
whose first batch did not contain any change documents.
62+
- Deprecated :meth:`pymongo.mongo_client.MongoClient.fsync`. Use
63+
:meth:`~pymongo.database.Database.command` to run the ``fsync`` command
64+
instead.
65+
- Deprecated :meth:`pymongo.mongo_client.MongoClient.unlock`. Use
66+
:meth:`~pymongo.database.Database.command` to run the ``fsyncUnlock`` command
67+
instead. See the documentation for more information.
68+
- Deprecated :attr:`pymongo.mongo_client.MongoClient.is_locked`. Use
69+
:meth:`~pymongo.database.Database.command` to run the ``currentOp`` command
70+
instead. See the documentation for more information.
5971

6072
Unavoidable breaking changes:
6173

pymongo/mongo_client.py

Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2083,15 +2083,33 @@ def _database_default_options(self, name):
20832083

20842084
@property
20852085
def is_locked(self):
2086-
"""Is this server locked? While locked, all write operations
2087-
are blocked, although read operations may still be allowed.
2086+
"""**DEPRECATED**: Is this server locked? While locked, all write
2087+
operations are blocked, although read operations may still be allowed.
20882088
Use :meth:`unlock` to unlock.
2089+
2090+
Deprecated. Users of MongoDB version 3.2 or newer can run the
2091+
`currentOp command`_ directly with
2092+
:meth:`~pymongo.database.Database.command`::
2093+
2094+
is_locked = client.admin.command('currentOp').get('fsyncLock')
2095+
2096+
Users of MongoDB version 2.6 and 3.0 can query the "inprog" virtual
2097+
collection::
2098+
2099+
is_locked = client.admin["$cmd.sys.inprog"].find_one().get('fsyncLock')
2100+
2101+
.. versionchanged:: 3.11
2102+
Deprecated.
2103+
2104+
.. _currentOp command: https://docs.mongodb.com/manual/reference/command/currentOp/
20892105
"""
2106+
warnings.warn("is_locked is deprecated. See the documentation for "
2107+
"more information.", DeprecationWarning, stacklevel=2)
20902108
ops = self._database_default_options('admin')._current_op()
20912109
return bool(ops.get('fsyncLock', 0))
20922110

20932111
def fsync(self, **kwargs):
2094-
"""Flush all pending writes to datafiles.
2112+
"""**DEPRECATED**: Flush all pending writes to datafiles.
20952113
20962114
Optional parameters can be passed as keyword arguments:
20972115
- `lock`: If True lock the server to disallow writes.
@@ -2106,6 +2124,14 @@ def fsync(self, **kwargs):
21062124
options = {'async': True}
21072125
client.fsync(**options)
21082126
2127+
Deprecated. Run the `fsync command`_ directly with
2128+
:meth:`~pymongo.database.Database.command` instead. For example::
2129+
2130+
client.admin.command('fsync', lock=True)
2131+
2132+
.. versionchanged:: 3.11
2133+
Deprecated.
2134+
21092135
.. versionchanged:: 3.6
21102136
Added ``session`` parameter.
21112137
@@ -2114,20 +2140,46 @@ def fsync(self, **kwargs):
21142140
.. warning:: MongoDB does not support the `async` option
21152141
on Windows and will raise an exception on that
21162142
platform.
2143+
2144+
.. _fsync command: https://docs.mongodb.com/manual/reference/command/fsync/
21172145
"""
2146+
warnings.warn("fsync is deprecated. Use "
2147+
"client.admin.command('fsync') instead.",
2148+
DeprecationWarning, stacklevel=2)
21182149
self.admin.command("fsync",
21192150
read_preference=ReadPreference.PRIMARY, **kwargs)
21202151

21212152
def unlock(self, session=None):
2122-
"""Unlock a previously locked server.
2153+
"""**DEPRECATED**: Unlock a previously locked server.
21232154
21242155
:Parameters:
21252156
- `session` (optional): a
21262157
:class:`~pymongo.client_session.ClientSession`.
21272158
2159+
Deprecated. Users of MongoDB version 3.2 or newer can run the
2160+
`fsyncUnlock command`_ directly with
2161+
:meth:`~pymongo.database.Database.command`::
2162+
2163+
client.admin.command('fsyncUnlock')
2164+
2165+
Users of MongoDB version 2.6 and 3.0 can query the "unlock" virtual
2166+
collection::
2167+
2168+
client.admin["$cmd.sys.unlock"].find_one()
2169+
2170+
.. versionchanged:: 3.11
2171+
Deprecated.
2172+
21282173
.. versionchanged:: 3.6
21292174
Added ``session`` parameter.
2175+
2176+
.. _fsyncUnlock command: https://docs.mongodb.com/manual/reference/command/fsyncUnlock/
21302177
"""
2178+
warnings.warn("unlock is deprecated. Use "
2179+
"client.admin.command('fsyncUnlock') instead. For "
2180+
"MongoDB 2.6 and 3.0, see the documentation for "
2181+
"more information.",
2182+
DeprecationWarning, stacklevel=2)
21312183
cmd = SON([("fsyncUnlock", 1)])
21322184
with self._socket_for_writes(session) as sock_info:
21332185
if sock_info.max_wire_version >= 4:

test/test_client.py

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1120,6 +1120,7 @@ def test_ipv6(self):
11201120
self.assertTrue("pymongo_test" in dbs)
11211121
self.assertTrue("pymongo_test_bernie" in dbs)
11221122

1123+
@ignore_deprecations
11231124
@client_context.require_no_mongos
11241125
def test_fsync_lock_unlock(self):
11251126
if server_is_master_with_slave(client_context.client):
@@ -1143,13 +1144,19 @@ def test_fsync_lock_unlock(self):
11431144
time.sleep(1)
11441145
self.assertFalse(locked)
11451146

1146-
def test_is_locked_does_not_raise_warning(self):
1147-
client = rs_or_single_client()
1148-
with warnings.catch_warnings(record=True) as ctx:
1149-
warnings.simplefilter("always")
1150-
_ = client.is_locked
1151-
self.assertFalse(
1152-
any(issubclass(w.category, DeprecationWarning) for w in ctx))
1147+
def test_deprecated_methods(self):
1148+
with warnings.catch_warnings():
1149+
warnings.simplefilter("error", DeprecationWarning)
1150+
with self.assertRaisesRegex(DeprecationWarning,
1151+
'is_locked is deprecated'):
1152+
_ = self.client.is_locked
1153+
if not client_context.is_mongos:
1154+
with self.assertRaisesRegex(DeprecationWarning,
1155+
'fsync is deprecated'):
1156+
self.client.fsync(lock=True)
1157+
with self.assertRaisesRegex(DeprecationWarning,
1158+
'unlock is deprecated'):
1159+
self.client.unlock()
11531160

11541161
def test_contextlib(self):
11551162
client = rs_or_single_client()

test/test_monitoring.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
unittest)
3838
from test.utils import (EventListener,
3939
get_pool,
40+
ignore_deprecations,
4041
rs_or_single_client,
4142
single_client,
4243
wait_until)
@@ -1336,12 +1337,13 @@ def test_first_batch_helper(self):
13361337
self.assertTrue('ok' in succeeded.reply)
13371338

13381339
if not client_context.is_mongos:
1339-
self.client.fsync(lock=True)
1340-
self.listener.results.clear()
1341-
self.client.unlock()
1342-
# Wait for async unlock...
1343-
wait_until(
1344-
lambda: not self.client.is_locked, "unlock the database")
1340+
with ignore_deprecations():
1341+
self.client.fsync(lock=True)
1342+
self.listener.results.clear()
1343+
self.client.unlock()
1344+
# Wait for async unlock...
1345+
wait_until(
1346+
lambda: not self.client.is_locked, "unlock the database")
13451347
started = results['started'][0]
13461348
succeeded = results['succeeded'][0]
13471349
self.assertEqual(0, len(results['failed']))

test/test_session.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,7 @@ def test_end_sessions(self):
227227
client.close()
228228
self.assertEqual(len(listener.results['started']), 0)
229229

230+
@ignore_deprecations # fsync and unlock
230231
def test_client(self):
231232
client = self.client
232233

0 commit comments

Comments
 (0)