PYTHON-1104 - maxStalenessMS -> maxStalenessSeconds.

This commit is contained in:
A. Jesse Jiryu Davis 2016-10-24 17:22:36 -04:00
parent 6bc48727de
commit f4922da97c
40 changed files with 69 additions and 290 deletions

View File

@ -13,7 +13,7 @@ Highlights include:
- Unicode aware string comparison using :doc:`examples/collations`.
- Support for the new :class:`~bson.decimal128.Decimal128` BSON type.
- A new maxStalenessMS read preference option.
- A new maxStalenessSeconds read preference option.
- :meth:`~pymongo.collection.Collection.parallel_scan` supports maxTimeMS.
- :attr:`~pymongo.write_concern.WriteConcern` is automatically
applied by all helpers for commands that write to the database when

View File

@ -44,8 +44,7 @@ def _parse_read_preference(options):
mode = options.get('readpreference', 0)
tags = options.get('readpreferencetags')
# common.validate() has converted from ms to seconds.
max_staleness = options.get('maxstalenessms')
max_staleness = options.get('maxstalenessseconds')
return make_read_preference(mode, tags, max_staleness)

View File

@ -286,6 +286,15 @@ def validate_timeout_or_zero(option, value):
return validate_positive_float(option, value) / 1000.0
def validate_max_staleness(option, value):
"""Validates a timeout specified in seconds returning
a value in floating point seconds.
"""
if value is None:
return value
return validate_positive_float(option, value)
def validate_read_preference(dummy, value):
"""Validate a read preference.
"""
@ -495,7 +504,7 @@ TIMEOUT_VALIDATORS = {
'serverselectiontimeoutms': validate_timeout_or_zero,
'heartbeatfrequencyms': validate_timeout_or_none,
'maxidletimems': validate_timeout_or_none,
'maxstalenessms': validate_timeout_or_none
'maxstalenessseconds': validate_max_staleness,
}
KW_VALIDATORS = {

View File

@ -12,7 +12,7 @@
# implied. See the License for the specific language governing
# permissions and limitations under the License.
"""Criteria to select ServerDescriptions based on maxStalenessMS.
"""Criteria to select ServerDescriptions based on maxStalenessSeconds.
The Max Staleness Spec says: When there is a known primary P,
a secondary S's staleness is estimated with this formula:
@ -79,10 +79,10 @@ def select(max_staleness, selection):
# Server Selection Spec: "A driver MUST raise an error if the
# TopologyType is ReplicaSetWithPrimary or ReplicaSetNoPrimary and
# maxStalenessMS is less than twice heartbeatFrequencyMS."
# maxStalenessSeconds * 1000 is less than twice heartbeatFrequencyMS."
if max_staleness < 2 * selection.heartbeat_frequency:
raise ConfigurationError(
"maxStalenessMS must be twice heartbeatFrequencyMS")
"maxStalenessSeconds must be twice heartbeatFrequencyMS")
if selection.primary:
return _with_primary(max_staleness, selection)

View File

@ -77,8 +77,8 @@ def _maybe_add_read_preference(spec, read_preference):
# Only add $readPreference if it's something other than primary to avoid
# problems with mongos versions that don't support read preferences. Also,
# for maximum backwards compatibility, don't add $readPreference for
# secondaryPreferred unless tags or maxStalenessMS are in use (setting the
# slaveOkay bit has the same effect).
# secondaryPreferred unless tags or maxStalenessSeconds are in use (setting
# the slaveOkay bit has the same effect).
if mode and (
mode != ReadPreference.SECONDARY_PREFERRED.mode
or tag_sets != [{}]

View File

@ -252,10 +252,10 @@ class MongoClient(common.BaseObject):
- `readPreferenceTags`: Specifies a tag set as a comma-separated list
of colon-separated key-value pairs. For example ``dc:ny,rack:1``.
Defaults to ``None``.
- `maxStalenessMS`: (integer or float, in milliseconds) The maximum
estimated length of time a replica set secondary can fall behind
the primary in replication before it will no longer be selected for
operations. Defaults to ``None`` (no limit).
- `maxStalenessSeconds`: (integer or float) The maximum estimated
length of time a replica set secondary can fall behind the primary
in replication before it will no longer be selected for operations.
Defaults to ``None`` (no limit).
| **SSL configuration:**

View File

@ -108,7 +108,7 @@ class _ServerMode(object):
if self.__tag_sets not in (None, [{}]):
doc['tags'] = self.__tag_sets
if self.__max_staleness:
doc['maxStalenessMS'] = int(self.__max_staleness * 1000)
doc['maxStalenessSeconds'] = int(self.__max_staleness)
return doc
@property
@ -145,8 +145,8 @@ class _ServerMode(object):
def min_wire_version(self):
"""The wire protocol version the server must support.
Some read preferences impose version requirements on all servers in the
topology (e.g. maxStalenessMS requires MongoDB 3.4 / maxWireVersion 5).
Some read preferences impose version requirements on all servers (e.g.
maxStalenessSeconds requires MongoDB 3.4 / maxWireVersion 5).
All servers' maxWireVersion must be at least this read preference's
`min_wire_version`, or the driver raises
@ -347,7 +347,7 @@ def make_read_preference(mode, tag_sets, max_staleness=None):
"cannot be combined with tags")
if max_staleness:
raise ConfigurationError("Read preference primary cannot be "
"combined with maxStalenessMS")
"combined with maxStalenessSeconds")
return Primary()
return _ALL_READ_PREFERENCES[mode](tag_sets, max_staleness)

View File

@ -1,7 +1,7 @@
{
"error": true,
"read_preference": {
"maxStalenessMS": 120000,
"maxStalenessSeconds": 120,
"mode": "Nearest"
},
"topology_description": {

View File

@ -15,7 +15,7 @@
}
],
"read_preference": {
"maxStalenessMS": 50000,
"maxStalenessSeconds": 50,
"mode": "Nearest"
},
"suitable_servers": [
@ -37,7 +37,7 @@
"lastUpdateTime": 25002,
"lastWrite": {
"lastWriteDate": {
"$numberLong": "1"
"$numberLong": "2"
}
},
"maxWireVersion": 5,
@ -64,7 +64,7 @@
"lastUpdateTime": 25002,
"lastWrite": {
"lastWriteDate": {
"$numberLong": "1"
"$numberLong": "2"
}
},
"maxWireVersion": 5,

View File

@ -15,7 +15,7 @@
}
],
"read_preference": {
"maxStalenessMS": 50000,
"maxStalenessSeconds": 50,
"mode": "Nearest"
},
"suitable_servers": [

View File

@ -15,7 +15,7 @@
}
],
"read_preference": {
"maxStalenessMS": 50000,
"maxStalenessSeconds": 50,
"mode": "Nearest"
},
"suitable_servers": [

View File

@ -15,7 +15,7 @@
}
],
"read_preference": {
"maxStalenessMS": 50000,
"maxStalenessSeconds": 50,
"mode": "PrimaryPreferred"
},
"suitable_servers": [

View File

@ -18,7 +18,7 @@
}
],
"read_preference": {
"maxStalenessMS": 50000,
"maxStalenessSeconds": 50,
"mode": "PrimaryPreferred",
"tag_sets": [
{

View File

@ -18,7 +18,7 @@
}
],
"read_preference": {
"maxStalenessMS": 50000,
"maxStalenessSeconds": 50,
"mode": "Secondary",
"tag_sets": [
{

View File

@ -14,7 +14,7 @@
}
],
"read_preference": {
"maxStalenessMS": 120000,
"maxStalenessSeconds": 120,
"mode": "SecondaryPreferred"
},
"suitable_servers": [

View File

@ -18,7 +18,7 @@
}
],
"read_preference": {
"maxStalenessMS": 50000,
"maxStalenessSeconds": 50,
"mode": "SecondaryPreferred",
"tag_sets": [
{

View File

@ -1,7 +1,7 @@
{
"error": true,
"read_preference": {
"maxStalenessMS": 120000,
"maxStalenessSeconds": 120,
"mode": "Nearest"
},
"topology_description": {

View File

@ -15,7 +15,7 @@
}
],
"read_preference": {
"maxStalenessMS": 50000,
"maxStalenessSeconds": 50,
"mode": "Nearest"
},
"suitable_servers": [

View File

@ -1,7 +1,7 @@
{
"error": true,
"read_preference": {
"maxStalenessMS": 1,
"maxStalenessSeconds": 1,
"mode": "Nearest"
},
"topology_description": {

View File

@ -1,7 +1,7 @@
{
"error": true,
"read_preference": {
"maxStalenessMS": 120000
"maxStalenessSeconds": 120
},
"topology_description": {
"servers": [

View File

@ -15,7 +15,7 @@
}
],
"read_preference": {
"maxStalenessMS": 50000,
"maxStalenessSeconds": 50,
"mode": "Nearest"
},
"suitable_servers": [

View File

@ -15,7 +15,7 @@
}
],
"read_preference": {
"maxStalenessMS": 50000,
"maxStalenessSeconds": 50,
"mode": "Nearest"
},
"suitable_servers": [

View File

@ -18,7 +18,7 @@
}
],
"read_preference": {
"maxStalenessMS": 50000,
"maxStalenessSeconds": 50,
"mode": "Nearest",
"tag_sets": [
{

View File

@ -15,7 +15,7 @@
}
],
"read_preference": {
"maxStalenessMS": 50000,
"maxStalenessSeconds": 50,
"mode": "PrimaryPreferred"
},
"suitable_servers": [

View File

@ -1,7 +1,7 @@
{
"error": true,
"read_preference": {
"maxStalenessMS": 50000,
"maxStalenessSeconds": 50,
"mode": "PrimaryPreferred"
},
"topology_description": {

View File

@ -14,7 +14,7 @@
}
],
"read_preference": {
"maxStalenessMS": 120000,
"maxStalenessSeconds": 120,
"mode": "SecondaryPreferred"
},
"suitable_servers": [

View File

@ -18,7 +18,7 @@
}
],
"read_preference": {
"maxStalenessMS": 50000,
"maxStalenessSeconds": 50,
"mode": "SecondaryPreferred",
"tag_sets": [
{

View File

@ -18,7 +18,7 @@
}
],
"read_preference": {
"maxStalenessMS": 50000,
"maxStalenessSeconds": 50,
"mode": "SecondaryPreferred",
"tag_sets": [
{

View File

@ -18,7 +18,7 @@
}
],
"read_preference": {
"maxStalenessMS": 50000,
"maxStalenessSeconds": 50,
"mode": "Secondary",
"tag_sets": [
{

View File

@ -18,7 +18,7 @@
}
],
"read_preference": {
"maxStalenessMS": 50000,
"maxStalenessSeconds": 50,
"mode": "Secondary",
"tag_sets": [
{

View File

@ -1,76 +0,0 @@
{
"heartbeatFrequencyMS": 1000,
"in_latency_window": [
{
"address": "b:27017",
"avg_rtt_ms": 5,
"lastUpdateTime": 0,
"lastWrite": {
"lastWriteDate": {
"$numberLong": "1"
}
},
"maxWireVersion": 5,
"type": "RSSecondary"
}
],
"read_preference": {
"maxStalenessMS": 2000,
"mode": "Nearest"
},
"suitable_servers": [
{
"address": "a:27017",
"avg_rtt_ms": 50,
"lastUpdateTime": 0,
"lastWrite": {
"lastWriteDate": {
"$numberLong": "1"
}
},
"maxWireVersion": 5,
"type": "RSPrimary"
},
{
"address": "b:27017",
"avg_rtt_ms": 5,
"lastUpdateTime": 0,
"lastWrite": {
"lastWriteDate": {
"$numberLong": "1"
}
},
"maxWireVersion": 5,
"type": "RSSecondary"
}
],
"topology_description": {
"servers": [
{
"address": "a:27017",
"avg_rtt_ms": 50,
"lastUpdateTime": 0,
"lastWrite": {
"lastWriteDate": {
"$numberLong": "1"
}
},
"maxWireVersion": 5,
"type": "RSPrimary"
},
{
"address": "b:27017",
"avg_rtt_ms": 5,
"lastUpdateTime": 0,
"lastWrite": {
"lastWriteDate": {
"$numberLong": "1"
}
},
"maxWireVersion": 5,
"type": "RSSecondary"
}
],
"type": "ReplicaSetWithPrimary"
}
}

View File

@ -1,76 +0,0 @@
{
"heartbeatFrequencyMS": 1000,
"in_latency_window": [
{
"address": "a:27017",
"avg_rtt_ms": 5,
"lastUpdateTime": 0,
"lastWrite": {
"lastWriteDate": {
"$numberLong": "1"
}
},
"maxWireVersion": 5,
"type": "RSPrimary"
}
],
"read_preference": {
"maxStalenessMS": 2000,
"mode": "Nearest"
},
"suitable_servers": [
{
"address": "a:27017",
"avg_rtt_ms": 5,
"lastUpdateTime": 0,
"lastWrite": {
"lastWriteDate": {
"$numberLong": "1"
}
},
"maxWireVersion": 5,
"type": "RSPrimary"
},
{
"address": "b:27017",
"avg_rtt_ms": 50,
"lastUpdateTime": 0,
"lastWrite": {
"lastWriteDate": {
"$numberLong": "1"
}
},
"maxWireVersion": 5,
"type": "RSSecondary"
}
],
"topology_description": {
"servers": [
{
"address": "a:27017",
"avg_rtt_ms": 5,
"lastUpdateTime": 0,
"lastWrite": {
"lastWriteDate": {
"$numberLong": "1"
}
},
"maxWireVersion": 5,
"type": "RSPrimary"
},
{
"address": "b:27017",
"avg_rtt_ms": 50,
"lastUpdateTime": 0,
"lastWrite": {
"lastWriteDate": {
"$numberLong": "1"
}
},
"maxWireVersion": 5,
"type": "RSSecondary"
}
],
"type": "ReplicaSetWithPrimary"
}
}

View File

@ -1,75 +0,0 @@
{
"in_latency_window": [
{
"address": "b:27017",
"avg_rtt_ms": 5,
"lastUpdateTime": 0,
"lastWrite": {
"lastWriteDate": {
"$numberLong": "1"
}
},
"maxWireVersion": 5,
"type": "RSSecondary"
}
],
"read_preference": {
"maxStalenessMS": 0,
"mode": "Nearest"
},
"suitable_servers": [
{
"address": "a:27017",
"avg_rtt_ms": 50,
"lastUpdateTime": 0,
"lastWrite": {
"lastWriteDate": {
"$numberLong": "1000001"
}
},
"maxWireVersion": 5,
"type": "RSPrimary"
},
{
"address": "b:27017",
"avg_rtt_ms": 5,
"lastUpdateTime": 0,
"lastWrite": {
"lastWriteDate": {
"$numberLong": "1"
}
},
"maxWireVersion": 5,
"type": "RSSecondary"
}
],
"topology_description": {
"servers": [
{
"address": "a:27017",
"avg_rtt_ms": 50,
"lastUpdateTime": 0,
"lastWrite": {
"lastWriteDate": {
"$numberLong": "1000001"
}
},
"maxWireVersion": 5,
"type": "RSPrimary"
},
{
"address": "b:27017",
"avg_rtt_ms": 5,
"lastUpdateTime": 0,
"lastWrite": {
"lastWriteDate": {
"$numberLong": "1"
}
},
"maxWireVersion": 5,
"type": "RSSecondary"
}
],
"type": "ReplicaSetWithPrimary"
}
}

View File

@ -1,7 +1,7 @@
{
"error": true,
"read_preference": {
"maxStalenessMS": 120000,
"maxStalenessSeconds": 120,
"mode": "Nearest"
},
"topology_description": {

View File

@ -15,7 +15,7 @@
}
],
"read_preference": {
"maxStalenessMS": 1,
"maxStalenessSeconds": 1,
"mode": "Nearest"
},
"suitable_servers": [

View File

@ -1,7 +1,7 @@
{
"error": true,
"read_preference": {
"maxStalenessMS": 120000,
"maxStalenessSeconds": 120,
"mode": "Nearest"
},
"topology_description": {

View File

@ -15,7 +15,7 @@
}
],
"read_preference": {
"maxStalenessMS": 1,
"maxStalenessSeconds": 1,
"mode": "Nearest"
},
"suitable_servers": [

View File

@ -2,7 +2,7 @@
"heartbeatFrequencyMS": 10000,
"in_latency_window": [],
"read_preference": {
"maxStalenessMS": 1,
"maxStalenessSeconds": 1,
"mode": "Nearest"
},
"suitable_servers": [],

View File

@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
"""Test maxStalenessMS support."""
"""Test maxStalenessSeconds support."""
import datetime
import os
@ -158,9 +158,7 @@ def create_test(scenario_def):
mode_string = pref_def.get('mode', 'primary')
mode_string = mode_string[:1].lower() + mode_string[1:]
mode = read_preferences.read_pref_mode_from_name(mode_string)
max_staleness = pref_def.get('maxStalenessMS', 0) / 1000.0
if not max_staleness:
max_staleness = None
max_staleness = pref_def.get('maxStalenessSeconds')
tag_sets = pref_def.get('tag_sets')
if scenario_def.get('error'):
@ -224,19 +222,19 @@ class TestMaxStaleness(unittest.TestCase):
def test_max_staleness(self):
# These tests are specified in max-staleness-tests.rst.
with self.assertRaises(ConfigurationError):
MongoClient("mongodb://a/?maxStalenessMS=120000")
MongoClient("mongodb://a/?maxStalenessSeconds=120")
with self.assertRaises(ConfigurationError):
MongoClient("mongodb://a/?readPreference=primary&"
"maxStalenessMS=120000")
"maxStalenessSeconds=120")
client = MongoClient("mongodb://host/?readPreference=secondary&"
"maxStalenessMS=120000")
"maxStalenessSeconds=120")
self.assertEqual(120, client.read_preference.max_staleness)
client = MongoClient("mongodb://a/?readPreference=secondary&"
"maxStalenessMS=1")
self.assertEqual(0.001, client.read_preference.max_staleness)
"maxStalenessSeconds=1")
self.assertEqual(1, client.read_preference.max_staleness)
if __name__ == "__main__":

View File

@ -469,7 +469,7 @@ class TestMongosAndReadPreference(unittest.TestCase):
pref.document,
{'mode': 'primaryPreferred',
'tags': [{'dc': 'sf'}],
'maxStalenessMS': 30000})
'maxStalenessSeconds': 30})
pref = Secondary()
self.assertEqual(
@ -485,7 +485,7 @@ class TestMongosAndReadPreference(unittest.TestCase):
pref.document,
{'mode': 'secondary',
'tags': [{'dc': 'sf'}],
'maxStalenessMS': 30000})
'maxStalenessSeconds': 30})
pref = SecondaryPreferred()
self.assertEqual(
@ -501,7 +501,7 @@ class TestMongosAndReadPreference(unittest.TestCase):
pref.document,
{'mode': 'secondaryPreferred',
'tags': [{'dc': 'sf'}],
'maxStalenessMS': 30000})
'maxStalenessSeconds': 30})
pref = Nearest()
self.assertEqual(
@ -517,7 +517,7 @@ class TestMongosAndReadPreference(unittest.TestCase):
pref.document,
{'mode': 'nearest',
'tags': [{'dc': 'sf'}],
'maxStalenessMS': 30000})
'maxStalenessSeconds': 30})
def test_maybe_add_read_preference(self):
@ -614,7 +614,7 @@ class TestMongosAndReadPreference(unittest.TestCase):
@client_context.require_mongos
@client_context.require_version_min(3, 3, 12)
def test_mongos_max_staleness(self):
# Sanity check that we're sending maxStalenessMS
# Sanity check that we're sending maxStalenessSeconds
coll = client_context.client.pymongo_test.get_collection(
"test", read_preference=SecondaryPreferred(max_staleness=120))
# No error
@ -631,13 +631,13 @@ class TestMongosAndReadPreference(unittest.TestCase):
coll = single_client(
readPreference='secondaryPreferred',
maxStalenessMS=120000).pymongo_test.test
maxStalenessSeconds=120).pymongo_test.test
# No error
coll.find_one()
coll = single_client(
readPreference='secondaryPreferred',
maxStalenessMS=10000).pymongo_test.test
maxStalenessSeconds=10).pymongo_test.test
try:
coll.find_one()
except OperationFailure as exc: