<commit_before>module Mongo
  class PoolManager
    include Mongo::ReadPreference
    include ThreadLocalVariableManager

    attr_reader :client,
                :arbiters,
                :primary,
                :secondaries,
                :primary_pool,
                :secondary_pools,
                :hosts,
                :nodes,
                :members,
                :seeds,
                :pools

    # Create a new set of connection pools.
    #
    # The pool manager will by default use the original seed list passed
    # to the connection objects, accessible via connection.seeds. In addition,
    # the user may pass an additional list of seeds nodes discovered in real
    # time. The union of these lists will be used when attempting to connect,
    # with the newly-discovered nodes being used first.
    def initialize(client, seeds=[])
      @client               = client
      @seeds                = seeds

      @pools                = Set.new
      @primary              = nil
      @primary_pool         = nil
      @secondaries          = Set.new
      @secondary_pools      = []
      @hosts                = Set.new
      @members              = Set.new
      @refresh_required     = false
    end

    def inspect
      "<Mongo::PoolManager:0x#{self.object_id.to_s(16)} @seeds=#{@seeds}>"
    end

    def connect
      @refresh_required = false
      disconnect_old_members
      connect_to_members
      initialize_pools(@members)
      cache_discovered_seeds
    end

    def refresh!(additional_seeds)
      @seeds |= additional_seeds
      connect
    end

    # We're healthy if all members are pingable and if the view
    # of the replica set returned by isMaster is equivalent
    # to our view. If any of these isn't the case,
    # set @refresh_required to true, and return.
    def check_connection_health
      begin
        seed = get_valid_seed_node
      rescue ConnectionFailure
        @refresh_required = true
        return
      end

      config = seed.config
      if config
        @refresh_required = true
        seed.close
        return
      end

      if config['hosts'].length != @members.length
        @refresh_required = true
        seed.close
        return
      end

      config['hosts'].each do |host|
        member = @members.detect do |m|
          m.address == host
        end

        if member && validate_existing_member(member)
          next
        else
          @refresh_required = true
          seed.close
          return false
        end
      end

      seed.close
    end

    # The replica set connection should initiate a full refresh.
    def refresh_required?
      @refresh_required
    end

    def closed?
      pools.all? { |pool| pool.closed? }
    end

    def close(opts={})
      begin
        pools.each { |pool| pool.close(opts) }
      rescue ConnectionFailure
      end
    end

    def read
      read_pool.host_port
    end

    def read_pool(mode=@client.read,
                  tags=@client.tag_sets,
                  acceptable_latency=@client.acceptable_latency)

      pinned = thread_local[:pinned_pools][self.object_id]

      if pinned && pinned.matches_mode(mode) && pinned.matches_tag_sets(tags) && pinned.up?
        pool = pinned
      else
        pool = select_pool(mode, tags, acceptable_latency)
      end

      unless pool
        raise ConnectionFailure, "No replica set member available for query " +
          "with read preference matching mode #{mode} and tags matching #{tags}."
      end

      pool
    end

    def max_bson_size
      @max_bson_size ||= config_min('maxBsonObjectSize', DEFAULT_MAX_BSON_SIZE)
    end

    def max_message_size
      @max_message_size ||= config_min('maxMessageSizeBytes', DEFAULT_MAX_MESSAGE_SIZE)
    end

    private

    def validate_existing_member(member)
      config = member.config
      if config
        return false
      else
        if member.primary?
          if member.last_state == :primary<commit_msg>RUBY-543 fix for broken logic in the pool manager refresh<commit_after>module Mongo
  class PoolManager
    include Mongo::ReadPreference
    include ThreadLocalVariableManager

    attr_reader :client,
                :arbiters,
                :primary,
                :secondaries,
                :primary_pool,
                :secondary_pools,
                :hosts,
                :nodes,
                :members,
                :seeds,
                :pools

    # Create a new set of connection pools.
    #
    # The pool manager will by default use the original seed list passed
    # to the connection objects, accessible via connection.seeds. In addition,
    # the user may pass an additional list of seeds nodes discovered in real
    # time. The union of these lists will be used when attempting to connect,
    # with the newly-discovered nodes being used first.
    def initialize(client, seeds=[])
      @client               = client
      @seeds                = seeds

      @pools                = Set.new
      @primary              = nil
      @primary_pool         = nil
      @secondaries          = Set.new
      @secondary_pools      = []
      @hosts                = Set.new
      @members              = Set.new
      @refresh_required     = false
    end

    def inspect
      "<Mongo::PoolManager:0x#{self.object_id.to_s(16)} @seeds=#{@seeds}>"
    end

    def connect
      @refresh_required = false
      disconnect_old_members
      connect_to_members
      initialize_pools(@members)
      cache_discovered_seeds
    end

    def refresh!(additional_seeds)
      @seeds |= additional_seeds
      connect
    end

    # We're healthy if all members are pingable and if the view
    # of the replica set returned by isMaster is equivalent
    # to our view. If any of these isn't the case,
    # set @refresh_required to true, and return.
    def check_connection_health
      begin
        seed = get_valid_seed_node
      rescue ConnectionFailure
        @refresh_required = true
        return
      end

      if !seed.config
        @refresh_required = true
        seed.close
        return
      end

      if seed.config['hosts'].length != @members.length
        @refresh_required = true
        seed.close
        return
      end

      seed.config['hosts'].each do |host|
        member = @members.detect do |m|
          m.address == host
        end

        if member && validate_existing_member(member)
          next
        else
          @refresh_required = true
          seed.close
          return false
        end
      end

      seed.close
    end

    # The replica set connection should initiate a full refresh.
    def refresh_required?
      @refresh_required
    end

    def closed?
      pools.all? { |pool| pool.closed? }
    end

    def close(opts={})
      begin
        pools.each { |pool| pool.close(opts) }
      rescue ConnectionFailure
      end
    end

    def read
      read_pool.host_port
    end

    def read_pool(mode=@client.read,
                  tags=@client.tag_sets,
                  acceptable_latency=@client.acceptable_latency)

      pinned = thread_local[:pinned_pools][self.object_id]

      if pinned && pinned.matches_mode(mode) && pinned.matches_tag_sets(tags) && pinned.up?
        pool = pinned
      else
        pool = select_pool(mode, tags, acceptable_latency)
      end

      unless pool
        raise ConnectionFailure, "No replica set member available for query " +
          "with read preference matching mode #{mode} and tags matching #{tags}."
      end

      pool
    end

    def max_bson_size
      @max_bson_size ||= config_min('maxBsonObjectSize', DEFAULT_MAX_BSON_SIZE)
    end

    def max_message_size
      @max_message_size ||= config_min('maxMessageSizeBytes', DEFAULT_MAX_MESSAGE_SIZE)
    end

    private

    def validate_existing_member(member)
      if !member.config
        return false
      else
        if member.primary?
          if member.last_state == :primary
{'fraction_non_alphanumeric': 0.06704119850187266, 'fraction_numerical': 0.0011235955056179776, 'mean_word_length': 1.8337460205164486, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7295479', 'n_tokens_mistral': 2248, 'n_tokens_neox': 2126, 'n_words': 634}