PYTHON-5169 - Deprecate Hedged Reads option (#2213)
Co-authored-by: Shane Harvey <shnhrv@gmail.com>
This commit is contained in:
parent
eea8a37257
commit
2c1a1608f2
@ -14,6 +14,11 @@ PyMongo 4.12 brings a number of changes including:
|
||||
- Added index hinting support to the
|
||||
:meth:`~pymongo.asynchronous.collection.AsyncCollection.distinct` and
|
||||
:meth:`~pymongo.collection.Collection.distinct` commands.
|
||||
- Deprecated the ``hedge`` parameter for
|
||||
:class:`~pymongo.read_preferences.PrimaryPreferred`,
|
||||
:class:`~pymongo.read_preferences.Secondary`,
|
||||
:class:`~pymongo.read_preferences.SecondaryPreferred`,
|
||||
:class:`~pymongo.read_preferences.Nearest`. Support for ``hedge`` will be removed in PyMongo 5.0.
|
||||
|
||||
Issues Resolved
|
||||
...............
|
||||
|
||||
@ -19,6 +19,7 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import warnings
|
||||
from collections import abc
|
||||
from typing import TYPE_CHECKING, Any, Mapping, Optional, Sequence
|
||||
|
||||
@ -103,6 +104,11 @@ def _validate_hedge(hedge: Optional[_Hedge]) -> Optional[_Hedge]:
|
||||
if not isinstance(hedge, dict):
|
||||
raise TypeError(f"hedge must be a dictionary, not {hedge!r}")
|
||||
|
||||
warnings.warn(
|
||||
"The read preference 'hedge' option is deprecated in PyMongo 4.12+ because hedged reads are deprecated in MongoDB version 8.0+. Support for 'hedge' will be removed in PyMongo 5.0.",
|
||||
DeprecationWarning,
|
||||
stacklevel=4,
|
||||
)
|
||||
return hedge
|
||||
|
||||
|
||||
@ -183,7 +189,9 @@ class _ServerMode:
|
||||
|
||||
@property
|
||||
def hedge(self) -> Optional[_Hedge]:
|
||||
"""The read preference ``hedge`` parameter.
|
||||
"""**DEPRECATED** - The read preference 'hedge' option is deprecated in PyMongo 4.12+ because hedged reads are deprecated in MongoDB version 8.0+. Support for 'hedge' will be removed in PyMongo 5.0.
|
||||
|
||||
The read preference ``hedge`` parameter.
|
||||
|
||||
A dictionary that configures how the server will perform hedged reads.
|
||||
It consists of the following keys:
|
||||
@ -203,6 +211,12 @@ class _ServerMode:
|
||||
|
||||
.. versionadded:: 3.11
|
||||
"""
|
||||
if self.__hedge is not None:
|
||||
warnings.warn(
|
||||
"The read preference 'hedge' option is deprecated in PyMongo 4.12+ because hedged reads are deprecated in MongoDB version 8.0+. Support for 'hedge' will be removed in PyMongo 5.0.",
|
||||
DeprecationWarning,
|
||||
stacklevel=2,
|
||||
)
|
||||
return self.__hedge
|
||||
|
||||
@property
|
||||
@ -312,7 +326,7 @@ class PrimaryPreferred(_ServerMode):
|
||||
replication before it will no longer be selected for operations.
|
||||
Default -1, meaning no maximum. If it is set, it must be at least
|
||||
90 seconds.
|
||||
:param hedge: The :attr:`~hedge` to use if the primary is not available.
|
||||
:param hedge: **DEPRECATED** - The :attr:`~hedge` for this read preference.
|
||||
|
||||
.. versionchanged:: 3.11
|
||||
Added ``hedge`` parameter.
|
||||
@ -354,7 +368,7 @@ class Secondary(_ServerMode):
|
||||
replication before it will no longer be selected for operations.
|
||||
Default -1, meaning no maximum. If it is set, it must be at least
|
||||
90 seconds.
|
||||
:param hedge: The :attr:`~hedge` for this read preference.
|
||||
:param hedge: **DEPRECATED** - The :attr:`~hedge` for this read preference.
|
||||
|
||||
.. versionchanged:: 3.11
|
||||
Added ``hedge`` parameter.
|
||||
@ -397,7 +411,7 @@ class SecondaryPreferred(_ServerMode):
|
||||
replication before it will no longer be selected for operations.
|
||||
Default -1, meaning no maximum. If it is set, it must be at least
|
||||
90 seconds.
|
||||
:param hedge: The :attr:`~hedge` for this read preference.
|
||||
:param hedge: **DEPRECATED** - The :attr:`~hedge` for this read preference.
|
||||
|
||||
.. versionchanged:: 3.11
|
||||
Added ``hedge`` parameter.
|
||||
@ -441,7 +455,7 @@ class Nearest(_ServerMode):
|
||||
replication before it will no longer be selected for operations.
|
||||
Default -1, meaning no maximum. If it is set, it must be at least
|
||||
90 seconds.
|
||||
:param hedge: The :attr:`~hedge` for this read preference.
|
||||
:param hedge: **DEPRECATED** - The :attr:`~hedge` for this read preference.
|
||||
|
||||
.. versionchanged:: 3.11
|
||||
Added ``hedge`` parameter.
|
||||
|
||||
@ -35,6 +35,7 @@ from test.asynchronous import (
|
||||
)
|
||||
from test.utils_shared import (
|
||||
OvertCommandListener,
|
||||
_ignore_deprecations,
|
||||
async_wait_until,
|
||||
one,
|
||||
)
|
||||
@ -542,33 +543,44 @@ class TestMongosAndReadPreference(AsyncIntegrationTest):
|
||||
for mode, cls in cases.items():
|
||||
with self.assertRaises(TypeError):
|
||||
cls(hedge=[]) # type: ignore
|
||||
with _ignore_deprecations():
|
||||
pref = cls(hedge={})
|
||||
self.assertEqual(pref.document, {"mode": mode})
|
||||
out = _maybe_add_read_preference({}, pref)
|
||||
if cls == SecondaryPreferred:
|
||||
# SecondaryPreferred without hedge doesn't add $readPreference.
|
||||
self.assertEqual(out, {})
|
||||
else:
|
||||
self.assertEqual(out, SON([("$query", {}), ("$readPreference", pref.document)]))
|
||||
|
||||
pref = cls(hedge={})
|
||||
self.assertEqual(pref.document, {"mode": mode})
|
||||
out = _maybe_add_read_preference({}, pref)
|
||||
if cls == SecondaryPreferred:
|
||||
# SecondaryPreferred without hedge doesn't add $readPreference.
|
||||
self.assertEqual(out, {})
|
||||
else:
|
||||
hedge: dict[str, Any] = {"enabled": True}
|
||||
pref = cls(hedge=hedge)
|
||||
self.assertEqual(pref.document, {"mode": mode, "hedge": hedge})
|
||||
out = _maybe_add_read_preference({}, pref)
|
||||
self.assertEqual(out, SON([("$query", {}), ("$readPreference", pref.document)]))
|
||||
|
||||
hedge: dict[str, Any] = {"enabled": True}
|
||||
pref = cls(hedge=hedge)
|
||||
self.assertEqual(pref.document, {"mode": mode, "hedge": hedge})
|
||||
out = _maybe_add_read_preference({}, pref)
|
||||
self.assertEqual(out, SON([("$query", {}), ("$readPreference", pref.document)]))
|
||||
hedge = {"enabled": False}
|
||||
pref = cls(hedge=hedge)
|
||||
self.assertEqual(pref.document, {"mode": mode, "hedge": hedge})
|
||||
out = _maybe_add_read_preference({}, pref)
|
||||
self.assertEqual(out, SON([("$query", {}), ("$readPreference", pref.document)]))
|
||||
|
||||
hedge = {"enabled": False}
|
||||
pref = cls(hedge=hedge)
|
||||
self.assertEqual(pref.document, {"mode": mode, "hedge": hedge})
|
||||
out = _maybe_add_read_preference({}, pref)
|
||||
self.assertEqual(out, SON([("$query", {}), ("$readPreference", pref.document)]))
|
||||
hedge = {"enabled": False, "extra": "option"}
|
||||
pref = cls(hedge=hedge)
|
||||
self.assertEqual(pref.document, {"mode": mode, "hedge": hedge})
|
||||
out = _maybe_add_read_preference({}, pref)
|
||||
self.assertEqual(out, SON([("$query", {}), ("$readPreference", pref.document)]))
|
||||
|
||||
hedge = {"enabled": False, "extra": "option"}
|
||||
pref = cls(hedge=hedge)
|
||||
self.assertEqual(pref.document, {"mode": mode, "hedge": hedge})
|
||||
out = _maybe_add_read_preference({}, pref)
|
||||
self.assertEqual(out, SON([("$query", {}), ("$readPreference", pref.document)]))
|
||||
def test_read_preference_hedge_deprecated(self):
|
||||
cases = {
|
||||
"primaryPreferred": PrimaryPreferred,
|
||||
"secondary": Secondary,
|
||||
"secondaryPreferred": SecondaryPreferred,
|
||||
"nearest": Nearest,
|
||||
}
|
||||
for _, cls in cases.items():
|
||||
with self.assertRaises(DeprecationWarning):
|
||||
cls(hedge={"enabled": True})
|
||||
|
||||
async def test_send_hedge(self):
|
||||
cases = {
|
||||
@ -582,7 +594,8 @@ class TestMongosAndReadPreference(AsyncIntegrationTest):
|
||||
client = await self.async_rs_client(event_listeners=[listener])
|
||||
await client.admin.command("ping")
|
||||
for _mode, cls in cases.items():
|
||||
pref = cls(hedge={"enabled": True})
|
||||
with _ignore_deprecations():
|
||||
pref = cls(hedge={"enabled": True})
|
||||
coll = client.test.get_collection("test", read_preference=pref)
|
||||
listener.reset()
|
||||
await coll.find_one()
|
||||
|
||||
@ -35,6 +35,7 @@ from test import (
|
||||
)
|
||||
from test.utils_shared import (
|
||||
OvertCommandListener,
|
||||
_ignore_deprecations,
|
||||
one,
|
||||
wait_until,
|
||||
)
|
||||
@ -522,33 +523,44 @@ class TestMongosAndReadPreference(IntegrationTest):
|
||||
for mode, cls in cases.items():
|
||||
with self.assertRaises(TypeError):
|
||||
cls(hedge=[]) # type: ignore
|
||||
with _ignore_deprecations():
|
||||
pref = cls(hedge={})
|
||||
self.assertEqual(pref.document, {"mode": mode})
|
||||
out = _maybe_add_read_preference({}, pref)
|
||||
if cls == SecondaryPreferred:
|
||||
# SecondaryPreferred without hedge doesn't add $readPreference.
|
||||
self.assertEqual(out, {})
|
||||
else:
|
||||
self.assertEqual(out, SON([("$query", {}), ("$readPreference", pref.document)]))
|
||||
|
||||
pref = cls(hedge={})
|
||||
self.assertEqual(pref.document, {"mode": mode})
|
||||
out = _maybe_add_read_preference({}, pref)
|
||||
if cls == SecondaryPreferred:
|
||||
# SecondaryPreferred without hedge doesn't add $readPreference.
|
||||
self.assertEqual(out, {})
|
||||
else:
|
||||
hedge: dict[str, Any] = {"enabled": True}
|
||||
pref = cls(hedge=hedge)
|
||||
self.assertEqual(pref.document, {"mode": mode, "hedge": hedge})
|
||||
out = _maybe_add_read_preference({}, pref)
|
||||
self.assertEqual(out, SON([("$query", {}), ("$readPreference", pref.document)]))
|
||||
|
||||
hedge: dict[str, Any] = {"enabled": True}
|
||||
pref = cls(hedge=hedge)
|
||||
self.assertEqual(pref.document, {"mode": mode, "hedge": hedge})
|
||||
out = _maybe_add_read_preference({}, pref)
|
||||
self.assertEqual(out, SON([("$query", {}), ("$readPreference", pref.document)]))
|
||||
hedge = {"enabled": False}
|
||||
pref = cls(hedge=hedge)
|
||||
self.assertEqual(pref.document, {"mode": mode, "hedge": hedge})
|
||||
out = _maybe_add_read_preference({}, pref)
|
||||
self.assertEqual(out, SON([("$query", {}), ("$readPreference", pref.document)]))
|
||||
|
||||
hedge = {"enabled": False}
|
||||
pref = cls(hedge=hedge)
|
||||
self.assertEqual(pref.document, {"mode": mode, "hedge": hedge})
|
||||
out = _maybe_add_read_preference({}, pref)
|
||||
self.assertEqual(out, SON([("$query", {}), ("$readPreference", pref.document)]))
|
||||
hedge = {"enabled": False, "extra": "option"}
|
||||
pref = cls(hedge=hedge)
|
||||
self.assertEqual(pref.document, {"mode": mode, "hedge": hedge})
|
||||
out = _maybe_add_read_preference({}, pref)
|
||||
self.assertEqual(out, SON([("$query", {}), ("$readPreference", pref.document)]))
|
||||
|
||||
hedge = {"enabled": False, "extra": "option"}
|
||||
pref = cls(hedge=hedge)
|
||||
self.assertEqual(pref.document, {"mode": mode, "hedge": hedge})
|
||||
out = _maybe_add_read_preference({}, pref)
|
||||
self.assertEqual(out, SON([("$query", {}), ("$readPreference", pref.document)]))
|
||||
def test_read_preference_hedge_deprecated(self):
|
||||
cases = {
|
||||
"primaryPreferred": PrimaryPreferred,
|
||||
"secondary": Secondary,
|
||||
"secondaryPreferred": SecondaryPreferred,
|
||||
"nearest": Nearest,
|
||||
}
|
||||
for _, cls in cases.items():
|
||||
with self.assertRaises(DeprecationWarning):
|
||||
cls(hedge={"enabled": True})
|
||||
|
||||
def test_send_hedge(self):
|
||||
cases = {
|
||||
@ -562,7 +574,8 @@ class TestMongosAndReadPreference(IntegrationTest):
|
||||
client = self.rs_client(event_listeners=[listener])
|
||||
client.admin.command("ping")
|
||||
for _mode, cls in cases.items():
|
||||
pref = cls(hedge={"enabled": True})
|
||||
with _ignore_deprecations():
|
||||
pref = cls(hedge={"enabled": True})
|
||||
coll = client.test.get_collection("test", read_preference=pref)
|
||||
listener.reset()
|
||||
coll.find_one()
|
||||
|
||||
Loading…
Reference in New Issue
Block a user