Module: Mongo::ReadPreference

Included in:
PoolManager
Defined in:
lib/mongo/util/read_preference.rb

Constant Summary collapse

READ_PREFERENCES =
[
  :primary,
  :primary_preferred,
  :secondary,
  :secondary_preferred,
  :nearest
]
MONGOS_MODES =
{
  :primary              => :primary,
  :primary_preferred    => :primaryPreferred,
  :secondary            => :secondary,
  :secondary_preferred  => :secondaryPreferred,
  :nearest              => :nearest
}

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.mongos(mode, tag_sets) ⇒ Object



19
20
21
22
23
24
25
# File 'lib/mongo/util/read_preference.rb', line 19

def self.mongos(mode, tag_sets)
  if mode != :secondary_preferred || !tag_sets.empty?
    mongos_read_preference = BSON::OrderedHash[:mode => MONGOS_MODES[mode]]
    mongos_read_preference[:tags] = tag_sets if !tag_sets.empty?
  end
  mongos_read_preference
end

.validate(value) ⇒ Object



27
28
29
30
31
32
33
34
# File 'lib/mongo/util/read_preference.rb', line 27

def self.validate(value)
  if READ_PREFERENCES.include?(value)
    return true
  else
    raise MongoArgumentError, "#{value} is not a valid read preference. " +
      "Please specify one of the following read preferences as a symbol: #{READ_PREFERENCES}"
  end
end

Instance Method Details

#select_near_pool(candidates, latency) ⇒ Object



74
75
76
77
78
79
80
# File 'lib/mongo/util/read_preference.rb', line 74

def select_near_pool(candidates, latency)
  nearest_pool = candidates.min_by { |candidate| candidate.ping_time }
  near_pools = candidates.select do |candidate|
    (candidate.ping_time - nearest_pool.ping_time) <= latency
  end
  near_pools[ rand(near_pools.length) ]
end

#select_pool(mode, tags, latency) ⇒ Object



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/mongo/util/read_preference.rb', line 36

def select_pool(mode, tags, latency)
  if mode == :primary && !tags.empty?
    raise MongoArgumentError, "Read preferecy :primary cannot be combined with tags"
  end

  case mode
    when :primary
      primary_pool
    when :primary_preferred
      primary_pool || select_secondary_pool(secondary_pools, tags, latency)
    when :secondary
      select_secondary_pool(secondary_pools, tags, latency)
    when :secondary_preferred
      select_secondary_pool(secondary_pools, tags, latency) || primary_pool
    when :nearest
      select_secondary_pool(pools, tags, latency)
  end
end

#select_secondary_pool(candidates, tag_sets, latency) ⇒ Object



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/mongo/util/read_preference.rb', line 55

def select_secondary_pool(candidates, tag_sets, latency)
  tag_sets = [tag_sets] unless tag_sets.is_a?(Array)

  if !tag_sets.empty?
    matches = []
    tag_sets.detect do |tag_set|
      matches = candidates.select do |candidate|
        tag_set.none? { |k,v| candidate.tags[k.to_s] != v } &&
        candidate.ping_time
      end
      !matches.empty?
    end
  else
    matches = candidates
  end

  matches.empty? ? nil : select_near_pool(matches, latency)
end