This file is indexed.

/usr/lib/python3/dist-packages/pymongo/max_staleness_selectors.py is in python3-pymongo 3.4.0-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# Copyright 2016 MongoDB, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you
# may not use this file except in compliance with the License.  You
# may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.  See the License for the specific language governing
# permissions and limitations under the License.

"""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:

  (S.lastUpdateTime - S.lastWriteDate) - (P.lastUpdateTime - P.lastWriteDate)
  + heartbeatFrequencyMS

When there is no known primary, a secondary S's staleness is estimated with:

  SMax.lastWriteDate - S.lastWriteDate + heartbeatFrequencyMS

where "SMax" is the secondary with the greatest lastWriteDate.
"""

from pymongo.errors import ConfigurationError
from pymongo.server_type import SERVER_TYPE


# Constant defined in Max Staleness Spec: An idle primary writes a no-op every
# 10 seconds to refresh secondaries' lastWriteDate values.
IDLE_WRITE_PERIOD = 10
SMALLEST_MAX_STALENESS = 90


def _validate_max_staleness(max_staleness,
                            heartbeat_frequency):
    # We checked for max staleness -1 before this, it must be positive here.
    if max_staleness < heartbeat_frequency + IDLE_WRITE_PERIOD:
        raise ConfigurationError(
            "maxStalenessSeconds must be at least heartbeatFrequencyMS +"
            " %d seconds. maxStalenessSeconds is set to %d,"
            " heartbeatFrequencyMS is set to %d." % (
                IDLE_WRITE_PERIOD, max_staleness, heartbeat_frequency * 1000))

    if max_staleness < SMALLEST_MAX_STALENESS:
        raise ConfigurationError(
            "maxStalenessSeconds must be at least %d. "
            "maxStalenessSeconds is set to %d." % (
                SMALLEST_MAX_STALENESS, max_staleness))


def _with_primary(max_staleness, selection):
    """Apply max_staleness, in seconds, to a Selection with a known primary."""
    primary = selection.primary
    sds = []

    for s in selection.server_descriptions:
        if s.server_type == SERVER_TYPE.RSSecondary:
            # See max-staleness.rst for explanation of this formula.
            staleness = (
                (s.last_update_time - s.last_write_date) -
                (primary.last_update_time - primary.last_write_date) +
                selection.heartbeat_frequency)

            if staleness <= max_staleness:
                sds.append(s)
        else:
            sds.append(s)

    return selection.with_server_descriptions(sds)


def _no_primary(max_staleness, selection):
    """Apply max_staleness, in seconds, to a Selection with no known primary."""
    # Secondary that's replicated the most recent writes.
    smax = selection.secondary_with_max_last_write_date()
    if not smax:
        # No secondaries and no primary, short-circuit out of here.
        return selection.with_server_descriptions([])

    sds = []

    for s in selection.server_descriptions:
        if s.server_type == SERVER_TYPE.RSSecondary:
            # See max-staleness.rst for explanation of this formula.
            staleness = (smax.last_write_date -
                         s.last_write_date +
                         selection.heartbeat_frequency)

            if staleness <= max_staleness:
                sds.append(s)
        else:
            sds.append(s)

    return selection.with_server_descriptions(sds)


def select(max_staleness, selection):
    """Apply max_staleness, in seconds, to a Selection."""
    if max_staleness == -1:
        return selection

    # Server Selection Spec: If the TopologyType is ReplicaSetWithPrimary or
    # ReplicaSetNoPrimary, a client MUST raise an error if maxStaleness <
    # heartbeatFrequency + IDLE_WRITE_PERIOD, or if maxStaleness < 90.
    _validate_max_staleness(max_staleness, selection.heartbeat_frequency)

    if selection.primary:
        return _with_primary(max_staleness, selection)
    else:
        return _no_primary(max_staleness, selection)