Uploaded image for project: 'Ruby Driver'
  1. Ruby Driver
  2. RUBY-132

sockets in connect_to_master

    • Type: Icon: Bug Bug
    • Resolution: Done
    • Priority: Icon: Major - P3 Major - P3
    • 12_01_17
    • Affects Version/s: None
    • Component/s: None
    • Labels:
      None

      Hey all,
      Discovered what I believe is a bug in the Ruby Mongo Driver
      version 1.0.1 in Mongo::Connection. The function connect_to_master
      creates a socket that it leaves dangling until the Ruby process that
      is using Mongo exits. I write up a fix to add that specific socket to
      the @sockets variable. I also think there is a separate bug where
      multiple threads invoking connect_to_master at exactly the same time
      causing multiple sockets to get created in parallel, potentially
      exceeding the pool limit.

      Attached is my attempt at a fix. Would love to know if others see
      this dangling socket issue where ... you would see it as 1 or 2
      permanent connections to mongo db for the life of your process ...
      depending on whether you call db.logoff/m.close in your client code.

      Greg

      1. Create a new socket and attempt to connect to master.
      2. If successful, sets host and port to master and returns the
        socket.
        #
      3. @raise [ConnectionFailure] if unable to connect to any host or
        port.
        def connect_to_master
        close
        @host = @port = nil
        for node_pair in @nodes
        host, port = *node_pair
        begin

      socket = nil
      begin
      socket = TCPSocket.new(host, port)
      socket.setsockopt(Socket::IPPROTO_TCP,
      Socket::TCP_NODELAY, 1)
      rescue => ex
      raise ConnectionFailure, "Failed to connect socket: #

      {ex}

      "
      end

      1. If we're connected to master, set the @host and @port
        result = self['admin'].command({:ismaster => 1}, false,
        false, socket)
        if result['ok'] == 1 && ((is_master = result['ismaster'] ==
        1) || @slave_ok)
        @connection_mutex.synchronize do
        @host, @port = host, port
        @sockets << socket
        apply_saved_authentication
        end
        end
      1. Note: slave_ok can be true only when connecting to a
        single node.
        if @nodes.length == 1 && !is_master && !@slave_ok
        raise ConfigurationError, "Trying to connect directly to
        slave; " +
        "if this is what you want, specify :slave_ok => true."
        end

      break if is_master || @slave_ok
      rescue SocketError, SystemCallError, IOError => ex
      socket.close if socket
      close
      false
      end
      end
      raise ConnectionFailure, "failed to connect to any given
      host:port" unless socket
      end

            Assignee:
            kbanker Kyle Banker
            Reporter:
            kbanker Kyle Banker
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved: