@@ -81,17 +81,30 @@ def _validate_max_staleness(max_staleness):
81
81
return max_staleness
82
82
83
83
84
+ def _validate_hedge (hedge ):
85
+ """Validate hedge."""
86
+ if hedge is None :
87
+ return None
88
+
89
+ if not isinstance (hedge , dict ):
90
+ raise TypeError ("hedge must be a dictionary, not %r" % (hedge ,))
91
+
92
+ return hedge
93
+
94
+
84
95
class _ServerMode (object ):
85
96
"""Base class for all read preferences.
86
97
"""
87
98
88
- __slots__ = ("__mongos_mode" , "__mode" , "__tag_sets" , "__max_staleness" )
99
+ __slots__ = ("__mongos_mode" , "__mode" , "__tag_sets" , "__max_staleness" ,
100
+ "__hedge" )
89
101
90
- def __init__ (self , mode , tag_sets = None , max_staleness = - 1 ):
102
+ def __init__ (self , mode , tag_sets = None , max_staleness = - 1 , hedge = None ):
91
103
self .__mongos_mode = _MONGOS_MODES [mode ]
92
104
self .__mode = mode
93
105
self .__tag_sets = _validate_tag_sets (tag_sets )
94
106
self .__max_staleness = _validate_max_staleness (max_staleness )
107
+ self .__hedge = _validate_hedge (hedge )
95
108
96
109
@property
97
110
def name (self ):
@@ -114,6 +127,8 @@ def document(self):
114
127
doc ['tags' ] = self .__tag_sets
115
128
if self .__max_staleness != - 1 :
116
129
doc ['maxStalenessSeconds' ] = self .__max_staleness
130
+ if self .__hedge not in (None , {}):
131
+ doc ['hedge' ] = self .__hedge
117
132
return doc
118
133
119
134
@property
@@ -144,6 +159,30 @@ def max_staleness(self):
144
159
no longer be selected for operations, or -1 for no maximum."""
145
160
return self .__max_staleness
146
161
162
+ @property
163
+ def hedge (self ):
164
+ """The read preference ``hedge`` parameter.
165
+
166
+ A dictionary that configures how the server will perform hedged reads.
167
+ It consists of the following keys:
168
+
169
+ - ``enabled``: Enables or disables hedged reads in sharded clusters.
170
+
171
+ Hedged reads are automatically enabled in MongoDB 4.4+ when using a
172
+ ``nearest`` read preference. To explicitly enable hedged reads, set
173
+ the ``enabled`` key to ``true``::
174
+
175
+ >>> Nearest(hedge={'enabled': True})
176
+
177
+ To explicitly disable hedged reads, set the ``enabled`` key to
178
+ ``False``::
179
+
180
+ >>> Nearest(hedge={'enabled': False})
181
+
182
+ .. versionadded:: 3.11
183
+ """
184
+ return self .__hedge
185
+
147
186
@property
148
187
def min_wire_version (self ):
149
188
"""The wire protocol version the server must support.
@@ -158,14 +197,15 @@ def min_wire_version(self):
158
197
return 0 if self .__max_staleness == - 1 else 5
159
198
160
199
def __repr__ (self ):
161
- return "%s(tag_sets=%r, max_staleness=%r)" % (
162
- self .name , self .__tag_sets , self .__max_staleness )
200
+ return "%s(tag_sets=%r, max_staleness=%r, hedge=%r )" % (
201
+ self .name , self .__tag_sets , self .__max_staleness , self . __hedge )
163
202
164
203
def __eq__ (self , other ):
165
204
if isinstance (other , _ServerMode ):
166
205
return (self .mode == other .mode and
167
206
self .tag_sets == other .tag_sets and
168
- self .max_staleness == other .max_staleness )
207
+ self .max_staleness == other .max_staleness and
208
+ self .hedge == other .hedge )
169
209
return NotImplemented
170
210
171
211
def __ne__ (self , other ):
@@ -178,14 +218,16 @@ def __getstate__(self):
178
218
"""
179
219
return {'mode' : self .__mode ,
180
220
'tag_sets' : self .__tag_sets ,
181
- 'max_staleness' : self .__max_staleness }
221
+ 'max_staleness' : self .__max_staleness ,
222
+ 'hedge' : self .__hedge }
182
223
183
224
def __setstate__ (self , value ):
184
225
"""Restore from pickling."""
185
226
self .__mode = value ['mode' ]
186
227
self .__mongos_mode = _MONGOS_MODES [self .__mode ]
187
228
self .__tag_sets = _validate_tag_sets (value ['tag_sets' ])
188
229
self .__max_staleness = _validate_max_staleness (value ['max_staleness' ])
230
+ self .__hedge = _validate_hedge (value ['hedge' ])
189
231
190
232
191
233
class Primary (_ServerMode ):
@@ -234,14 +276,17 @@ class PrimaryPreferred(_ServerMode):
234
276
replication before it will no longer be selected for operations.
235
277
Default -1, meaning no maximum. If it is set, it must be at least
236
278
90 seconds.
279
+ - `hedge`: The :attr:`~hedge` to use if the primary is not available.
280
+
281
+ .. versionchanged:: 3.11
282
+ Added ``hedge`` parameter.
237
283
"""
238
284
239
285
__slots__ = ()
240
286
241
- def __init__ (self , tag_sets = None , max_staleness = - 1 ):
242
- super (PrimaryPreferred , self ).__init__ (_PRIMARY_PREFERRED ,
243
- tag_sets ,
244
- max_staleness )
287
+ def __init__ (self , tag_sets = None , max_staleness = - 1 , hedge = None ):
288
+ super (PrimaryPreferred , self ).__init__ (
289
+ _PRIMARY_PREFERRED , tag_sets , max_staleness , hedge )
245
290
246
291
def __call__ (self , selection ):
247
292
"""Apply this read preference to Selection."""
@@ -271,12 +316,17 @@ class Secondary(_ServerMode):
271
316
replication before it will no longer be selected for operations.
272
317
Default -1, meaning no maximum. If it is set, it must be at least
273
318
90 seconds.
319
+ - `hedge`: The :attr:`~hedge` for this read preference.
320
+
321
+ .. versionchanged:: 3.11
322
+ Added ``hedge`` parameter.
274
323
"""
275
324
276
325
__slots__ = ()
277
326
278
- def __init__ (self , tag_sets = None , max_staleness = - 1 ):
279
- super (Secondary , self ).__init__ (_SECONDARY , tag_sets , max_staleness )
327
+ def __init__ (self , tag_sets = None , max_staleness = - 1 , hedge = None ):
328
+ super (Secondary , self ).__init__ (
329
+ _SECONDARY , tag_sets , max_staleness , hedge )
280
330
281
331
def __call__ (self , selection ):
282
332
"""Apply this read preference to Selection."""
@@ -303,14 +353,17 @@ class SecondaryPreferred(_ServerMode):
303
353
replication before it will no longer be selected for operations.
304
354
Default -1, meaning no maximum. If it is set, it must be at least
305
355
90 seconds.
356
+ - `hedge`: The :attr:`~hedge` for this read preference.
357
+
358
+ .. versionchanged:: 3.11
359
+ Added ``hedge`` parameter.
306
360
"""
307
361
308
362
__slots__ = ()
309
363
310
- def __init__ (self , tag_sets = None , max_staleness = - 1 ):
311
- super (SecondaryPreferred , self ).__init__ (_SECONDARY_PREFERRED ,
312
- tag_sets ,
313
- max_staleness )
364
+ def __init__ (self , tag_sets = None , max_staleness = - 1 , hedge = None ):
365
+ super (SecondaryPreferred , self ).__init__ (
366
+ _SECONDARY_PREFERRED , tag_sets , max_staleness , hedge )
314
367
315
368
def __call__ (self , selection ):
316
369
"""Apply this read preference to Selection."""
@@ -342,12 +395,17 @@ class Nearest(_ServerMode):
342
395
replication before it will no longer be selected for operations.
343
396
Default -1, meaning no maximum. If it is set, it must be at least
344
397
90 seconds.
398
+ - `hedge`: The :attr:`~hedge` for this read preference.
399
+
400
+ .. versionchanged:: 3.11
401
+ Added ``hedge`` parameter.
345
402
"""
346
403
347
404
__slots__ = ()
348
405
349
- def __init__ (self , tag_sets = None , max_staleness = - 1 ):
350
- super (Nearest , self ).__init__ (_NEAREST , tag_sets , max_staleness )
406
+ def __init__ (self , tag_sets = None , max_staleness = - 1 , hedge = None ):
407
+ super (Nearest , self ).__init__ (
408
+ _NEAREST , tag_sets , max_staleness , hedge )
351
409
352
410
def __call__ (self , selection ):
353
411
"""Apply this read preference to Selection."""
0 commit comments