~ubuntu-branches/ubuntu/wily/pymongo/wily-proposed

« back to all changes in this revision

Viewing changes to pymongo/server_selectors.py

  • Committer: Package Import Robot
  • Author(s): Federico Ceratto
  • Date: 2015-04-26 22:43:13 UTC
  • mfrom: (24.1.5 sid)
  • Revision ID: package-import@ubuntu.com-20150426224313-0hga2jphvf0rrmfe
Tags: 3.0.1-1
New upstream release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright 2014-2015 MongoDB, Inc.
 
2
#
 
3
# Licensed under the Apache License, Version 2.0 (the "License"); you
 
4
# may not use this file except in compliance with the License.  You
 
5
# may obtain a copy of the License at
 
6
#
 
7
# http://www.apache.org/licenses/LICENSE-2.0
 
8
#
 
9
# Unless required by applicable law or agreed to in writing, software
 
10
# distributed under the License is distributed on an "AS IS" BASIS,
 
11
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 
12
# implied.  See the License for the specific language governing
 
13
# permissions and limitations under the License.
 
14
 
 
15
"""Criteria to select some ServerDescriptions out of a list."""
 
16
 
 
17
from pymongo.server_type import SERVER_TYPE
 
18
 
 
19
 
 
20
def any_server_selector(server_descriptions):
 
21
    return server_descriptions
 
22
 
 
23
 
 
24
def writable_server_selector(server_descriptions):
 
25
    return [s for s in server_descriptions if s.is_writable]
 
26
 
 
27
 
 
28
def secondary_server_selector(server_descriptions):
 
29
    return [s for s in server_descriptions
 
30
            if s.server_type == SERVER_TYPE.RSSecondary]
 
31
 
 
32
 
 
33
def arbiter_server_selector(server_descriptions):
 
34
    return [s for s in server_descriptions
 
35
            if s.server_type == SERVER_TYPE.RSArbiter]
 
36
 
 
37
 
 
38
def writable_preferred_server_selector(server_descriptions):
 
39
    """Like PrimaryPreferred but doesn't use tags or latency."""
 
40
    return writable_server_selector(server_descriptions) or server_descriptions
 
41
 
 
42
 
 
43
def single_tag_set_server_selector(tag_set, server_descriptions):
 
44
    """All servers matching one tag set.
 
45
 
 
46
    A tag set is a dict. A server matches if its tags are a superset:
 
47
    A server tagged {'a': '1', 'b': '2'} matches the tag set {'a': '1'}.
 
48
 
 
49
    The empty tag set {} matches any server.
 
50
    """
 
51
    def tags_match(server_tags):
 
52
        for key, value in tag_set.items():
 
53
            if key not in server_tags or server_tags[key] != value:
 
54
                return False
 
55
 
 
56
        return True
 
57
 
 
58
    return [s for s in server_descriptions if tags_match(s.tags)]
 
59
 
 
60
 
 
61
def tag_sets_server_selector(tag_sets, server_descriptions):
 
62
    """All servers match a list of tag sets.
 
63
 
 
64
    tag_sets is a list of dicts. The empty tag set {} matches any server,
 
65
    and may be provided at the end of the list as a fallback. So
 
66
    [{'a': 'value'}, {}] expresses a preference for servers tagged
 
67
    {'a': 'value'}, but accepts any server if none matches the first
 
68
    preference.
 
69
    """
 
70
    for tag_set in tag_sets:
 
71
        selected = single_tag_set_server_selector(tag_set, server_descriptions)
 
72
        if selected:
 
73
            return selected
 
74
 
 
75
    return []
 
76
 
 
77
 
 
78
def apply_local_threshold(latency_ms, server_descriptions):
 
79
    """All servers with round trip times within latency_ms of the fastest one.
 
80
 
 
81
    No ServerDescription's round_trip_time can be None.
 
82
    """
 
83
    if not server_descriptions:
 
84
        # Avoid ValueError from min() with empty sequence.
 
85
        return []
 
86
 
 
87
    # round_trip_time is in seconds.
 
88
    if any(s for s in server_descriptions if s.round_trip_time is None):
 
89
        raise ValueError("Not all servers' round trip times are known")
 
90
 
 
91
    fastest = min(s.round_trip_time for s in server_descriptions)
 
92
    return [
 
93
        s for s in server_descriptions
 
94
        if (s.round_trip_time - fastest) < latency_ms / 1000.]
 
95
 
 
96
 
 
97
def secondary_with_tags_server_selector(tag_sets, server_descriptions):
 
98
    """All near-enough secondaries matching the tag sets."""
 
99
    return tag_sets_server_selector(
 
100
        tag_sets, secondary_server_selector(server_descriptions))
 
101
 
 
102
 
 
103
def member_with_tags_server_selector(tag_sets, server_descriptions):
 
104
    """All near-enough members matching the tag sets."""
 
105
    return tag_sets_server_selector(tag_sets, server_descriptions)