mongo 1.5.2 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Rakefile +24 -8
- data/docs/HISTORY.md +15 -0
- data/docs/READ_PREFERENCE.md +1 -1
- data/docs/RELEASES.md +18 -4
- data/docs/REPLICA_SETS.md +5 -5
- data/docs/WRITE_CONCERN.md +1 -1
- data/lib/mongo/collection.rb +49 -10
- data/lib/mongo/connection.rb +7 -24
- data/lib/mongo/cursor.rb +3 -1
- data/lib/mongo/db.rb +5 -1
- data/lib/mongo/exceptions.rb +0 -3
- data/lib/mongo/gridfs/grid.rb +1 -1
- data/lib/mongo/gridfs/grid_file_system.rb +11 -3
- data/lib/mongo/networking.rb +7 -3
- data/lib/mongo/repl_set_connection.rb +58 -82
- data/lib/mongo/util/logging.rb +26 -18
- data/lib/mongo/util/node.rb +11 -2
- data/lib/mongo/util/pool_manager.rb +7 -5
- data/lib/mongo/util/support.rb +2 -2
- data/lib/mongo/util/uri_parser.rb +74 -36
- data/lib/mongo/version.rb +1 -1
- data/mongo.gemspec +2 -2
- data/test/auxillary/authentication_test.rb +8 -0
- data/test/auxillary/repl_set_auth_test.rb +1 -2
- data/test/bson/ordered_hash_test.rb +1 -1
- data/test/bson/test_helper.rb +2 -1
- data/test/collection_test.rb +71 -0
- data/test/connection_test.rb +9 -0
- data/test/db_test.rb +7 -0
- data/test/grid_file_system_test.rb +12 -0
- data/test/load/thin/load.rb +1 -1
- data/test/replica_sets/basic_test.rb +36 -26
- data/test/replica_sets/complex_connect_test.rb +44 -0
- data/test/replica_sets/connect_test.rb +48 -22
- data/test/replica_sets/count_test.rb +4 -6
- data/test/replica_sets/insert_test.rb +13 -14
- data/test/replica_sets/pooled_insert_test.rb +9 -10
- data/test/replica_sets/query_test.rb +4 -4
- data/test/replica_sets/read_preference_test.rb +48 -14
- data/test/replica_sets/refresh_test.rb +43 -42
- data/test/replica_sets/refresh_with_threads_test.rb +10 -9
- data/test/replica_sets/replication_ack_test.rb +3 -3
- data/test/replica_sets/rs_test_helper.rb +17 -11
- data/test/test_helper.rb +2 -1
- data/test/tools/repl_set_manager.rb +63 -39
- data/test/unit/collection_test.rb +2 -1
- data/test/unit/connection_test.rb +22 -0
- data/test/unit/cursor_test.rb +6 -3
- data/test/unit/read_test.rb +1 -1
- data/test/uri_test.rb +17 -2
- metadata +151 -167
    
        data/lib/mongo/exceptions.rb
    CHANGED
    
    
    
        data/lib/mongo/gridfs/grid.rb
    CHANGED
    
    | @@ -70,7 +70,7 @@ module Mongo | |
| 70 70 | 
             
                  opts     = opts.dup
         | 
| 71 71 | 
             
                  filename = opts[:filename]
         | 
| 72 72 | 
             
                  opts.merge!(default_grid_io_opts)
         | 
| 73 | 
            -
                  file = GridIO.new(@files, @chunks, filename, 'w', opts | 
| 73 | 
            +
                  file = GridIO.new(@files, @chunks, filename, 'w', opts)
         | 
| 74 74 | 
             
                  file.write(data)
         | 
| 75 75 | 
             
                  file.close
         | 
| 76 76 | 
             
                  file.files_id
         | 
| @@ -71,6 +71,9 @@ module Mongo | |
| 71 71 | 
             
                #  GridFileSystem#delete.
         | 
| 72 72 | 
             
                # @option opts [Boolean] :safe (false) When safe mode is enabled, the chunks sent to the server
         | 
| 73 73 | 
             
                #   will be validated using an md5 hash. If validation fails, an exception will be raised.
         | 
| 74 | 
            +
                # @option opts [Integer] :versions (false) deletes all versions which exceed the number specified to 
         | 
| 75 | 
            +
                #   retain ordered by uploadDate. This option only works in 'w' mode. Certain precautions must be taken when 
         | 
| 76 | 
            +
                #   deleting GridFS files. See the notes under GridFileSystem#delete.
         | 
| 74 77 | 
             
                #
         | 
| 75 78 | 
             
                # @example
         | 
| 76 79 | 
             
                #
         | 
| @@ -97,7 +100,12 @@ module Mongo | |
| 97 100 | 
             
                def open(filename, mode, opts={})
         | 
| 98 101 | 
             
                  opts = opts.dup
         | 
| 99 102 | 
             
                  opts.merge!(default_grid_io_opts(filename))
         | 
| 100 | 
            -
                   | 
| 103 | 
            +
                  if mode == 'w'
         | 
| 104 | 
            +
                    versions = opts.delete(:versions)
         | 
| 105 | 
            +
                    if opts.delete(:delete_old) || (versions && versions < 1)
         | 
| 106 | 
            +
                      versions = 1
         | 
| 107 | 
            +
                    end
         | 
| 108 | 
            +
                  end
         | 
| 101 109 | 
             
                  file = GridIO.new(@files, @chunks, filename, mode, opts)
         | 
| 102 110 | 
             
                  return file unless block_given?
         | 
| 103 111 | 
             
                  result = nil
         | 
| @@ -105,9 +113,9 @@ module Mongo | |
| 105 113 | 
             
                    result = yield file
         | 
| 106 114 | 
             
                  ensure
         | 
| 107 115 | 
             
                    id = file.close
         | 
| 108 | 
            -
                    if  | 
| 116 | 
            +
                    if versions
         | 
| 109 117 | 
             
                      self.delete do
         | 
| 110 | 
            -
                        @files.find({'filename' => filename, '_id' => {'$ne' => id}}, :fields => ['_id'])
         | 
| 118 | 
            +
                        @files.find({'filename' => filename, '_id' => {'$ne' => id}}, :fields => ['_id'], :sort => ['uploadDate', -1], :skip => (versions -1))
         | 
| 111 119 | 
             
                      end
         | 
| 112 120 | 
             
                    end
         | 
| 113 121 | 
             
                  end
         | 
    
        data/lib/mongo/networking.rb
    CHANGED
    
    | @@ -87,9 +87,13 @@ module Mongo | |
| 87 87 | 
             
                  end
         | 
| 88 88 |  | 
| 89 89 | 
             
                  if num_received == 1 && (error = docs[0]['err'] || docs[0]['errmsg'])
         | 
| 90 | 
            -
                     | 
| 91 | 
            -
             | 
| 92 | 
            -
             | 
| 90 | 
            +
                    if error.include?("not master")
         | 
| 91 | 
            +
                      close
         | 
| 92 | 
            +
                      raise ConnectionFailure.new(docs[0]['code'].to_s + ': ' + error, docs[0]['code'], docs[0])
         | 
| 93 | 
            +
                    else
         | 
| 94 | 
            +
                      error = "wtimeout" if error == "timeout"
         | 
| 95 | 
            +
                      raise OperationFailure.new(docs[0]['code'].to_s + ': ' + error, docs[0]['code'], docs[0])
         | 
| 96 | 
            +
                    end
         | 
| 93 97 | 
             
                  end
         | 
| 94 98 |  | 
| 95 99 | 
             
                  docs[0]
         | 
| @@ -20,7 +20,6 @@ module Mongo | |
| 20 20 |  | 
| 21 21 | 
             
              # Instantiates and manages connections to a MongoDB replica set.
         | 
| 22 22 | 
             
              class ReplSetConnection < Connection
         | 
| 23 | 
            -
                CLEANUP_INTERVAL = 300
         | 
| 24 23 |  | 
| 25 24 | 
             
                attr_reader :replica_set_name, :seeds, :refresh_interval, :refresh_mode,
         | 
| 26 25 | 
             
                  :refresh_version
         | 
| @@ -32,26 +31,25 @@ module Mongo | |
| 32 31 | 
             
                # Connection#arbiters. This is useful if your application needs to connect manually to nodes other
         | 
| 33 32 | 
             
                # than the primary.
         | 
| 34 33 | 
             
                #
         | 
| 35 | 
            -
                # @param [Array]  | 
| 36 | 
            -
                #   hash containing any options. See the examples below for exactly how to use the constructor.
         | 
| 34 | 
            +
                # @param [Array] seeds "host:port" strings
         | 
| 37 35 | 
             
                #
         | 
| 38 | 
            -
                # @option  | 
| 36 | 
            +
                # @option opts [String] :rs_name (nil) The name of the replica set to connect to. You
         | 
| 39 37 | 
             
                #   can use this option to verify that you're connecting to the right replica set.
         | 
| 40 | 
            -
                # @option  | 
| 38 | 
            +
                # @option opts [Boolean, Hash] :safe (false) Set the default safe-mode options
         | 
| 41 39 | 
             
                #   propogated to DB objects instantiated off of this Connection. This
         | 
| 42 40 | 
             
                #   default can be overridden upon instantiation of any DB by explicity setting a :safe value
         | 
| 43 41 | 
             
                #   on initialization.
         | 
| 44 | 
            -
                # @option  | 
| 42 | 
            +
                # @option opts [:primary, :secondary] :read (:primary) The default read preference for Mongo::DB
         | 
| 45 43 | 
             
                #   objects created from this connection object. If +:secondary+ is chosen, reads will be sent
         | 
| 46 44 | 
             
                #   to one of the closest available secondary nodes. If a secondary node cannot be located, the
         | 
| 47 45 | 
             
                #   read will be sent to the primary.
         | 
| 48 | 
            -
                # @option  | 
| 49 | 
            -
                # @option  | 
| 46 | 
            +
                # @option opts [Logger] :logger (nil) Logger instance to receive driver operation log.
         | 
| 47 | 
            +
                # @option opts [Integer] :pool_size (1) The maximum number of socket connections allowed per
         | 
| 50 48 | 
             
                #   connection pool. Note: this setting is relevant only for multi-threaded applications.
         | 
| 51 | 
            -
                # @option  | 
| 49 | 
            +
                # @option opts [Float] :pool_timeout (5.0) When all of the connections a pool are checked out,
         | 
| 52 50 | 
             
                #   this is the number of seconds to wait for a new connection to be released before throwing an exception.
         | 
| 53 51 | 
             
                #   Note: this setting is relevant only for multi-threaded applications.
         | 
| 54 | 
            -
                # @option opts [Float] :op_timeout ( | 
| 52 | 
            +
                # @option opts [Float] :op_timeout (nil) The number of seconds to wait for a read operation to time out.
         | 
| 55 53 | 
             
                # @option opts [Float] :connect_timeout (30) The number of seconds to wait before timing out a
         | 
| 56 54 | 
             
                #   connection attempt.
         | 
| 57 55 | 
             
                # @option opts [Boolean] :ssl (false) If true, create the connection to the server using SSL.
         | 
| @@ -63,17 +61,17 @@ module Mongo | |
| 63 61 | 
             
                #   between calls to check the replica set's state.
         | 
| 64 62 | 
             
                # @option opts [Boolean] :require_primary (true) If true, require a primary node for the connection
         | 
| 65 63 | 
             
                #   to succeed. Otherwise, connection will succeed as long as there's at least one secondary node.
         | 
| 64 | 
            +
                # Note: that the number of seed nodes does not have to be equal to the number of replica set members.
         | 
| 65 | 
            +
                # The purpose of seed nodes is to permit the driver to find at least one replica set member even if a member is down.
         | 
| 66 66 | 
             
                #
         | 
| 67 | 
            -
                # @example Connect to a replica set and provide two seed nodes. | 
| 68 | 
            -
                #    | 
| 69 | 
            -
                #   the driver to find at least one replica set member even if a member is down.
         | 
| 70 | 
            -
                #   ReplSetConnection.new(['localhost', 30000], ['localhost', 30001])
         | 
| 67 | 
            +
                # @example Connect to a replica set and provide two seed nodes.
         | 
| 68 | 
            +
                #   ReplSetConnection.new(['localhost:30000', 'localhost:30001'])
         | 
| 71 69 | 
             
                #
         | 
| 72 70 | 
             
                # @example Connect to a replica set providing two seed nodes and ensuring a connection to the replica set named 'prod':
         | 
| 73 | 
            -
                #   ReplSetConnection.new(['localhost',  | 
| 71 | 
            +
                #   ReplSetConnection.new(['localhost:30000', 'localhost:30001'], :name => 'prod')
         | 
| 74 72 | 
             
                #
         | 
| 75 73 | 
             
                # @example Connect to a replica set providing two seed nodes and allowing reads from a secondary node:
         | 
| 76 | 
            -
                #   ReplSetConnection.new(['localhost',  | 
| 74 | 
            +
                #   ReplSetConnection.new(['localhost:30000', 'localhost:30001'], :read => :secondary)
         | 
| 77 75 | 
             
                #
         | 
| 78 76 | 
             
                # @see http://api.mongodb.org/ruby/current/file.REPLICA_SETS.html Replica sets in Ruby
         | 
| 79 77 | 
             
                #
         | 
| @@ -85,23 +83,33 @@ module Mongo | |
| 85 83 | 
             
                  else
         | 
| 86 84 | 
             
                    opts = {}
         | 
| 87 85 | 
             
                  end
         | 
| 88 | 
            -
             | 
| 86 | 
            +
                  
         | 
| 89 87 | 
             
                  unless args.length > 0
         | 
| 90 88 | 
             
                    raise MongoArgumentError, "A ReplSetConnection requires at least one seed node."
         | 
| 91 89 | 
             
                  end
         | 
| 90 | 
            +
                  
         | 
| 91 | 
            +
                  # This is temporary until support for the old format is dropped
         | 
| 92 | 
            +
                  @seeds = []
         | 
| 93 | 
            +
                  if args.first.last.is_a?(Integer)
         | 
| 94 | 
            +
                    warn "Initiating a ReplSetConnection with seeds passed as individual [host, port] array arguments is deprecated."
         | 
| 95 | 
            +
                    warn "Please specify hosts as an array of 'host:port' strings; the old format will be removed in v2.0"
         | 
| 96 | 
            +
                    @seeds = args
         | 
| 97 | 
            +
                  else
         | 
| 98 | 
            +
                    args.first.map do |host_port|
         | 
| 99 | 
            +
                      seed = host_port.split(":")
         | 
| 100 | 
            +
                      seed[1] = seed[1].to_i
         | 
| 101 | 
            +
                      seeds << seed
         | 
| 102 | 
            +
                    end
         | 
| 103 | 
            +
                  end
         | 
| 92 104 |  | 
| 93 | 
            -
                  # The original, immutable list of seed node.
         | 
| 94 105 | 
             
                  # TODO: add a method for replacing this list of node.
         | 
| 95 | 
            -
                  @seeds = args
         | 
| 96 106 | 
             
                  @seeds.freeze
         | 
| 97 107 |  | 
| 98 | 
            -
                  # TODO: get rid of this
         | 
| 99 | 
            -
                  @nodes = @seeds.dup
         | 
| 100 | 
            -
             | 
| 101 108 | 
             
                  # Refresh
         | 
| 102 109 | 
             
                  @refresh_mode = opts.fetch(:refresh_mode, false)
         | 
| 103 110 | 
             
                  @refresh_interval = opts[:refresh_interval] || 90
         | 
| 104 111 | 
             
                  @last_refresh = Time.now
         | 
| 112 | 
            +
                  @refresh_version = 0
         | 
| 105 113 |  | 
| 106 114 | 
             
                  # No connection manager by default.
         | 
| 107 115 | 
             
                  @manager = nil
         | 
| @@ -127,7 +135,6 @@ module Mongo | |
| 127 135 | 
             
                  end
         | 
| 128 136 |  | 
| 129 137 | 
             
                  @connected = false
         | 
| 130 | 
            -
                  @refresh_version = 0
         | 
| 131 138 |  | 
| 132 139 | 
             
                  # Replica set name
         | 
| 133 140 | 
             
                  if opts[:rs_name]
         | 
| @@ -212,7 +219,6 @@ module Mongo | |
| 212 219 | 
             
                  @manager = background_manager
         | 
| 213 220 | 
             
                  old_manager.close(:soft => true)
         | 
| 214 221 | 
             
                  @refresh_version += 1
         | 
| 215 | 
            -
             | 
| 216 222 | 
             
                  return true
         | 
| 217 223 | 
             
                end
         | 
| 218 224 |  | 
| @@ -312,10 +318,8 @@ module Mongo | |
| 312 318 | 
             
                  else
         | 
| 313 319 | 
             
                    connect
         | 
| 314 320 | 
             
                  end
         | 
| 315 | 
            -
             | 
| 316 321 | 
             
                  begin
         | 
| 317 322 | 
             
                    socket = get_socket_from_pool(self.read_pool)
         | 
| 318 | 
            -
             | 
| 319 323 | 
             
                    if !socket
         | 
| 320 324 | 
             
                      connect
         | 
| 321 325 | 
             
                      socket = get_socket_from_pool(self.primary_pool)
         | 
| @@ -331,6 +335,26 @@ module Mongo | |
| 331 335 | 
             
                    raise ConnectionFailure.new("Could not connect to a node for reading.")
         | 
| 332 336 | 
             
                  end
         | 
| 333 337 | 
             
                end
         | 
| 338 | 
            +
                
         | 
| 339 | 
            +
                def checkout_secondary
         | 
| 340 | 
            +
                  if connected?
         | 
| 341 | 
            +
                    sync_refresh
         | 
| 342 | 
            +
                  else
         | 
| 343 | 
            +
                    connect
         | 
| 344 | 
            +
                  end
         | 
| 345 | 
            +
                  begin
         | 
| 346 | 
            +
                    socket = get_socket_from_pool(self.secondary_pool)
         | 
| 347 | 
            +
                  rescue => ex
         | 
| 348 | 
            +
                    checkin(socket) if socket
         | 
| 349 | 
            +
                    raise ex
         | 
| 350 | 
            +
                  end
         | 
| 351 | 
            +
             | 
| 352 | 
            +
                  if socket
         | 
| 353 | 
            +
                    socket
         | 
| 354 | 
            +
                  else
         | 
| 355 | 
            +
                    raise ConnectionFailure.new("Could not connect to a secondary for reading.")
         | 
| 356 | 
            +
                  end
         | 
| 357 | 
            +
                end
         | 
| 334 358 |  | 
| 335 359 | 
             
                # Checkout a socket for writing (i.e., a primary node).
         | 
| 336 360 | 
             
                def checkout_writer
         | 
| @@ -419,6 +443,10 @@ module Mongo | |
| 419 443 | 
             
                def read_pool
         | 
| 420 444 | 
             
                  @manager ? @manager.read_pool : nil
         | 
| 421 445 | 
             
                end
         | 
| 446 | 
            +
                
         | 
| 447 | 
            +
                def secondary_pool
         | 
| 448 | 
            +
                  @manager ? @manager.secondary_pool : nil
         | 
| 449 | 
            +
                end
         | 
| 422 450 |  | 
| 423 451 | 
             
                def secondary_pools
         | 
| 424 452 | 
             
                  @manager ? @manager.secondary_pools : []
         | 
| @@ -440,64 +468,12 @@ module Mongo | |
| 440 468 |  | 
| 441 469 | 
             
                # Generic initialization code.
         | 
| 442 470 | 
             
                def setup(opts)
         | 
| 443 | 
            -
                  # Default maximum BSON object size
         | 
| 444 | 
            -
                  @max_bson_size = Mongo::DEFAULT_MAX_BSON_SIZE
         | 
| 445 | 
            -
             | 
| 446 471 | 
             
                  @safe_mutex_lock = Mutex.new
         | 
| 447 472 | 
             
                  @safe_mutexes = Hash.new {|hash, key| hash[key] = Mutex.new}
         | 
| 448 | 
            -
             | 
| 449 | 
            -
                   | 
| 450 | 
            -
                   | 
| 451 | 
            -
                   | 
| 452 | 
            -
                    @socket_class = Mongo::SSLSocket
         | 
| 453 | 
            -
                  else
         | 
| 454 | 
            -
                    @socket_class = ::TCPSocket
         | 
| 455 | 
            -
                  end
         | 
| 456 | 
            -
             | 
| 457 | 
            -
                  # Authentication objects
         | 
| 458 | 
            -
                  @auths = opts.fetch(:auths, [])
         | 
| 459 | 
            -
             | 
| 460 | 
            -
                  # Lock for request ids.
         | 
| 461 | 
            -
                  @id_lock = Mutex.new
         | 
| 462 | 
            -
             | 
| 463 | 
            -
                  # Pool size and timeout.
         | 
| 464 | 
            -
                  @pool_size = opts[:pool_size] || 1
         | 
| 465 | 
            -
                  if opts[:timeout]
         | 
| 466 | 
            -
                    warn "The :timeout option has been deprecated " +
         | 
| 467 | 
            -
                      "and will be removed in the 2.0 release. Use :pool_timeout instead."
         | 
| 468 | 
            -
                  end
         | 
| 469 | 
            -
                  @pool_timeout = opts[:pool_timeout] || opts[:timeout] || 5.0
         | 
| 470 | 
            -
             | 
| 471 | 
            -
                  # Timeout on socket read operation.
         | 
| 472 | 
            -
                  @op_timeout = opts[:op_timeout] || 30
         | 
| 473 | 
            -
             | 
| 474 | 
            -
                  # Timeout on socket connect.
         | 
| 475 | 
            -
                  @connect_timeout = opts[:connect_timeout] || 30
         | 
| 476 | 
            -
             | 
| 477 | 
            -
                  # Mutex for synchronizing pool access
         | 
| 478 | 
            -
                  # TODO: remove this.
         | 
| 479 | 
            -
                  @connection_mutex = Mutex.new
         | 
| 480 | 
            -
             | 
| 481 | 
            -
                  # Global safe option. This is false by default.
         | 
| 482 | 
            -
                  @safe = opts[:safe] || false
         | 
| 483 | 
            -
             | 
| 484 | 
            -
                  # Condition variable for signal and wait
         | 
| 485 | 
            -
                  @queue = ConditionVariable.new
         | 
| 486 | 
            -
             | 
| 487 | 
            -
                  @logger = opts[:logger] || nil
         | 
| 488 | 
            -
             | 
| 489 | 
            -
                  # Clean up connections to dead threads.
         | 
| 490 | 
            -
                  @last_cleanup = Time.now
         | 
| 491 | 
            -
                  @cleanup_lock = Mutex.new
         | 
| 492 | 
            -
             | 
| 493 | 
            -
                  if @logger
         | 
| 494 | 
            -
                    write_logging_startup_message
         | 
| 495 | 
            -
                  end
         | 
| 496 | 
            -
             | 
| 497 | 
            -
                  @last_refresh = Time.now
         | 
| 498 | 
            -
             | 
| 499 | 
            -
                  should_connect = opts.fetch(:connect, true)
         | 
| 500 | 
            -
                  connect if should_connect
         | 
| 473 | 
            +
                  
         | 
| 474 | 
            +
                  opts[:connect_timeout] = opts[:connect_timeout] || 30
         | 
| 475 | 
            +
                  
         | 
| 476 | 
            +
                  super opts
         | 
| 501 477 | 
             
                end
         | 
| 502 478 |  | 
| 503 479 | 
             
                # Checkout a socket connected to a node with one of
         | 
    
        data/lib/mongo/util/logging.rb
    CHANGED
    
    | @@ -1,8 +1,10 @@ | |
| 1 1 | 
             
            module Mongo
         | 
| 2 2 | 
             
              module Logging
         | 
| 3 3 |  | 
| 4 | 
            +
                DEBUG_LEVEL = defined?(Logger) ? Logger::DEBUG : 0
         | 
| 5 | 
            +
             | 
| 4 6 | 
             
                def write_logging_startup_message
         | 
| 5 | 
            -
                  log(: | 
| 7 | 
            +
                  log(:debug, "Please note that logging negatively impacts client-side performance. " +
         | 
| 6 8 | 
             
                  "You should set your logging level no lower than :info in production.")
         | 
| 7 9 | 
             
                end
         | 
| 8 10 |  | 
| @@ -10,37 +12,43 @@ module Mongo | |
| 10 12 | 
             
                def log(level, msg)
         | 
| 11 13 | 
             
                  return unless @logger
         | 
| 12 14 | 
             
                  case level
         | 
| 13 | 
            -
                    when :debug then
         | 
| 14 | 
            -
                      @logger.debug "MONGODB [DEBUG] #{msg}"
         | 
| 15 | 
            -
                    when :warn then
         | 
| 16 | 
            -
                      @logger.warn "MONGODB [WARNING] #{msg}"
         | 
| 17 | 
            -
                    when :error then
         | 
| 18 | 
            -
                      @logger.error "MONGODB [ERROR] #{msg}"
         | 
| 19 15 | 
             
                    when :fatal then
         | 
| 20 16 | 
             
                      @logger.fatal "MONGODB [FATAL] #{msg}"
         | 
| 21 | 
            -
                     | 
| 17 | 
            +
                    when :error then
         | 
| 18 | 
            +
                      @logger.error "MONGODB [ERROR] #{msg}"
         | 
| 19 | 
            +
                    when :warn then
         | 
| 20 | 
            +
                      @logger.warn "MONGODB [WARNING] #{msg}"
         | 
| 21 | 
            +
                    when :info then
         | 
| 22 22 | 
             
                      @logger.info "MONGODB [INFO] #{msg}"
         | 
| 23 | 
            +
                    when :debug then
         | 
| 24 | 
            +
                      @logger.debug "MONGODB [DEBUG] #{msg}"
         | 
| 25 | 
            +
                    else
         | 
| 26 | 
            +
                      @logger.debug "MONGODB [DEBUG] #{msg}"
         | 
| 23 27 | 
             
                  end
         | 
| 24 28 | 
             
                end
         | 
| 25 29 |  | 
| 26 30 | 
             
                # Execute the block and log the operation described by name and payload.
         | 
| 27 31 | 
             
                def instrument(name, payload = {}, &blk)
         | 
| 32 | 
            +
                  start_time = Time.now
         | 
| 28 33 | 
             
                  res = yield
         | 
| 29 | 
            -
                   | 
| 34 | 
            +
                  if @logger && (@logger.level == DEBUG_LEVEL)
         | 
| 35 | 
            +
                    log_operation(name, payload, start_time)
         | 
| 36 | 
            +
                  end
         | 
| 30 37 | 
             
                  res
         | 
| 31 38 | 
             
                end
         | 
| 32 39 |  | 
| 33 40 | 
             
                protected
         | 
| 34 41 |  | 
| 35 | 
            -
                def log_operation(name, payload)
         | 
| 36 | 
            -
                   | 
| 37 | 
            -
                   | 
| 38 | 
            -
                  msg  | 
| 39 | 
            -
                  msg  | 
| 40 | 
            -
                  msg  | 
| 41 | 
            -
                  msg  | 
| 42 | 
            -
                  msg  | 
| 43 | 
            -
             | 
| 42 | 
            +
                def log_operation(name, payload, start_time)
         | 
| 43 | 
            +
                  msg = "MONGODB "
         | 
| 44 | 
            +
                  msg << "(#{((Time.now - start_time) * 1000).to_i}ms) "
         | 
| 45 | 
            +
                  msg << "#{payload[:database]}['#{payload[:collection]}'].#{name}("
         | 
| 46 | 
            +
                  msg << payload.values_at(:selector, :document, :documents, :fields ).compact.map(&:inspect).join(', ') + ")"
         | 
| 47 | 
            +
                  msg << ".skip(#{payload[:skip]})"   if payload[:skip]
         | 
| 48 | 
            +
                  msg << ".limit(#{payload[:limit]})" if payload[:limit]
         | 
| 49 | 
            +
                  msg << ".sort(#{payload[:order]})"  if payload[:order]
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                  @logger.debug(msg)
         | 
| 44 52 | 
             
                end
         | 
| 45 53 |  | 
| 46 54 | 
             
              end
         | 
    
        data/lib/mongo/util/node.rb
    CHANGED
    
    | @@ -101,7 +101,12 @@ module Mongo | |
| 101 101 | 
             
                  rescue ConnectionFailure, OperationFailure, OperationTimeout, SocketError, SystemCallError, IOError => ex
         | 
| 102 102 | 
             
                    @connection.log(:warn, "Attempted connection to node #{host_string} raised " +
         | 
| 103 103 | 
             
                                        "#{ex.class}: #{ex.message}")
         | 
| 104 | 
            -
                     | 
| 104 | 
            +
                    
         | 
| 105 | 
            +
                    # Socket may already be nil from issuing command
         | 
| 106 | 
            +
                    if @socket && !@socket.closed?
         | 
| 107 | 
            +
                      @socket.close
         | 
| 108 | 
            +
                    end
         | 
| 109 | 
            +
                    
         | 
| 105 110 | 
             
                    return nil
         | 
| 106 111 | 
             
                  end
         | 
| 107 112 |  | 
| @@ -166,12 +171,16 @@ module Mongo | |
| 166 171 | 
             
                  [host, port]
         | 
| 167 172 | 
             
                end
         | 
| 168 173 |  | 
| 169 | 
            -
                # Ensure that this node is a member of a replica set.
         | 
| 174 | 
            +
                # Ensure that this node is a healty member of a replica set.
         | 
| 170 175 | 
             
                def check_set_membership(config)
         | 
| 171 176 | 
             
                  if !config['hosts']
         | 
| 172 177 | 
             
                    message = "Will not connect to #{host_string} because it's not a member " +
         | 
| 173 178 | 
             
                      "of a replica set."
         | 
| 174 179 | 
             
                    raise ConnectionFailure, message
         | 
| 180 | 
            +
                  elsif config['hosts'].length == 1 && !config['ismaster'] &&
         | 
| 181 | 
            +
                    !config['secondary']
         | 
| 182 | 
            +
                    message = "Attempting to connect to an unhealthy, single-node replica set."
         | 
| 183 | 
            +
                    raise ConnectionFailure, message
         | 
| 175 184 | 
             
                  end
         | 
| 176 185 | 
             
                end
         | 
| 177 186 |  | 
| @@ -2,8 +2,8 @@ module Mongo | |
| 2 2 | 
             
              class PoolManager
         | 
| 3 3 |  | 
| 4 4 | 
             
                attr_reader :connection, :arbiters, :primary, :secondaries, :primary_pool,
         | 
| 5 | 
            -
                  :read_pool, :secondary_pools, :hosts, :nodes, | 
| 6 | 
            -
                  :tags_to_pools, :tag_map, :members
         | 
| 5 | 
            +
                  :read_pool, :secondary_pool, :secondary_pools, :hosts, :nodes,
         | 
| 6 | 
            +
                  :max_bson_size, :tags_to_pools, :tag_map, :members
         | 
| 7 7 |  | 
| 8 8 | 
             
                # Create a new set of connection pools.
         | 
| 9 9 | 
             
                #
         | 
| @@ -135,12 +135,12 @@ module Mongo | |
| 135 135 | 
             
                end
         | 
| 136 136 |  | 
| 137 137 | 
             
                def initialize_data
         | 
| 138 | 
            -
                  @seeds = []
         | 
| 139 138 | 
             
                  @primary = nil
         | 
| 140 139 | 
             
                  @primary_pool = nil
         | 
| 141 140 | 
             
                  @read_pool = nil
         | 
| 142 141 | 
             
                  @arbiters = []
         | 
| 143 142 | 
             
                  @secondaries = []
         | 
| 143 | 
            +
                  @secondary_pool = nil
         | 
| 144 144 | 
             
                  @secondary_pools = []
         | 
| 145 145 | 
             
                  @hosts = Set.new
         | 
| 146 146 | 
             
                  @members = Set.new
         | 
| @@ -234,11 +234,13 @@ module Mongo | |
| 234 234 | 
             
                # time to figure out which nodes to choose from.
         | 
| 235 235 | 
             
                def set_read_pool
         | 
| 236 236 | 
             
                  if @secondary_pools.empty?
         | 
| 237 | 
            -
             | 
| 237 | 
            +
                    @read_pool = @primary_pool
         | 
| 238 238 | 
             
                  elsif @secondary_pools.size == 1
         | 
| 239 | 
            -
             | 
| 239 | 
            +
                    @read_pool = @secondary_pools[0]
         | 
| 240 | 
            +
                    @secondary_pool = @read_pool
         | 
| 240 241 | 
             
                  else
         | 
| 241 242 | 
             
                    @read_pool = nearby_pool_from_set(@secondary_pools)
         | 
| 243 | 
            +
                    @secondary_pool = @read_pool
         | 
| 242 244 | 
             
                  end
         | 
| 243 245 | 
             
                end
         | 
| 244 246 |  |