mongo 1.8.0 → 1.8.2

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.
Files changed (80) hide show
  1. data/README.md +14 -29
  2. data/VERSION +1 -1
  3. data/lib/mongo.rb +3 -0
  4. data/lib/mongo/collection.rb +99 -49
  5. data/lib/mongo/cursor.rb +17 -17
  6. data/lib/mongo/db.rb +30 -14
  7. data/lib/mongo/gridfs/grid.rb +5 -3
  8. data/lib/mongo/gridfs/grid_file_system.rb +5 -3
  9. data/lib/mongo/gridfs/grid_io.rb +5 -3
  10. data/lib/mongo/legacy.rb +9 -2
  11. data/lib/mongo/mongo_client.rb +100 -72
  12. data/lib/mongo/mongo_replica_set_client.rb +46 -60
  13. data/lib/mongo/mongo_sharded_client.rb +5 -66
  14. data/lib/mongo/networking.rb +2 -1
  15. data/lib/mongo/util/node.rb +41 -42
  16. data/lib/mongo/util/pool.rb +15 -43
  17. data/lib/mongo/util/pool_manager.rb +16 -65
  18. data/lib/mongo/util/read_preference.rb +82 -0
  19. data/lib/mongo/util/sharding_pool_manager.rb +0 -86
  20. data/lib/mongo/util/ssl_socket.rb +2 -1
  21. data/lib/mongo/util/support.rb +8 -18
  22. data/lib/mongo/util/tcp_socket.rb +5 -4
  23. data/lib/mongo/util/thread_local_variable_manager.rb +29 -0
  24. data/lib/mongo/util/unix_socket.rb +23 -0
  25. data/lib/mongo/util/uri_parser.rb +31 -18
  26. data/lib/mongo/util/write_concern.rb +7 -2
  27. data/mongo.gemspec +1 -1
  28. data/test/auxillary/repl_set_auth_test.rb +2 -2
  29. data/test/bson/bson_test.rb +1 -1
  30. data/test/bson/byte_buffer_test.rb +24 -26
  31. data/test/bson/hash_with_indifferent_access_test.rb +11 -1
  32. data/test/functional/collection_test.rb +16 -16
  33. data/test/functional/connection_test.rb +1 -4
  34. data/test/functional/db_api_test.rb +14 -10
  35. data/test/functional/pool_test.rb +23 -31
  36. data/test/functional/timeout_test.rb +3 -5
  37. data/test/functional/uri_test.rb +10 -5
  38. data/test/replica_set/basic_test.rb +3 -8
  39. data/test/replica_set/client_test.rb +47 -31
  40. data/test/replica_set/complex_connect_test.rb +12 -10
  41. data/test/replica_set/connection_test.rb +8 -151
  42. data/test/replica_set/count_test.rb +9 -5
  43. data/test/replica_set/cursor_test.rb +17 -27
  44. data/test/replica_set/insert_test.rb +5 -10
  45. data/test/replica_set/query_test.rb +4 -9
  46. data/test/replica_set/read_preference_test.rb +200 -0
  47. data/test/replica_set/refresh_test.rb +54 -65
  48. data/test/replica_set/replication_ack_test.rb +16 -14
  49. data/test/sharded_cluster/basic_test.rb +30 -0
  50. data/test/test_helper.rb +33 -15
  51. data/test/threading/basic_test.rb +79 -0
  52. data/test/tools/mongo_config.rb +62 -22
  53. data/test/unit/client_test.rb +36 -14
  54. data/test/unit/collection_test.rb +23 -0
  55. data/test/unit/connection_test.rb +30 -14
  56. data/test/unit/cursor_test.rb +137 -7
  57. data/test/unit/db_test.rb +17 -4
  58. data/test/unit/grid_test.rb +2 -2
  59. data/test/unit/node_test.rb +2 -1
  60. data/test/unit/pool_manager_test.rb +29 -1
  61. data/test/unit/read_test.rb +15 -15
  62. data/test/unit/safe_test.rb +4 -4
  63. data/test/unit/write_concern_test.rb +4 -4
  64. metadata +134 -143
  65. data/examples/admin.rb +0 -43
  66. data/examples/capped.rb +0 -22
  67. data/examples/cursor.rb +0 -48
  68. data/examples/gridfs.rb +0 -44
  69. data/examples/index_test.rb +0 -126
  70. data/examples/info.rb +0 -31
  71. data/examples/queries.rb +0 -74
  72. data/examples/replica_set.rb +0 -26
  73. data/examples/simple.rb +0 -25
  74. data/examples/strict.rb +0 -35
  75. data/examples/types.rb +0 -36
  76. data/examples/web/thin/load.rb +0 -23
  77. data/examples/web/unicorn/load.rb +0 -25
  78. data/test/support/hash_with_indifferent_access.rb +0 -186
  79. data/test/support/keys.rb +0 -45
  80. data/test/threading/threading_with_large_pool_test.rb +0 -90
@@ -55,7 +55,7 @@ module Mongo
55
55
  attr_accessor :cache_time
56
56
 
57
57
  # Read Preference
58
- attr_accessor :read_preference, :tag_sets, :acceptable_latency
58
+ attr_accessor :read, :tag_sets, :acceptable_latency
59
59
 
60
60
  # Instances of DB are normally obtained by calling Mongo#db.
61
61
  #
@@ -71,11 +71,17 @@ module Mongo
71
71
  # fields the factory wishes to inject. (NOTE: if the object already has a primary key,
72
72
  # the factory should not inject a new key).
73
73
  #
74
- # @option opts [Hash] :w, :j, :wtimeout, :fsync Set the default write concern for this database.
75
- # Propagated to Collection objects instantiated off of this DB. If no
76
- # options are provided, the default write concern set on this instance's MongoClient object will be used. This
77
- # default can be overridden upon instantiation of any collection by explicitly setting write concern values
78
- # on initialization
74
+ # @option opts [String, Integer, Symbol] :w (1) Set default number of nodes to which a write
75
+ # should be acknowledged
76
+ # @option opts [Boolean] :j (false) Set journal acknowledgement
77
+ # @option opts [Integer] :wtimeout (nil) Set replica set acknowledgement timeout
78
+ # @option opts [Boolean] :fsync (false) Set fsync acknowledgement.
79
+ #
80
+ # Notes on write concern:
81
+ # These write concern options are propagated to Collection objects instantiated off of this DB. If no
82
+ # options are provided, the default write concern set on this instance's MongoClient object will be used. This
83
+ # default can be overridden upon instantiation of any collection by explicitly setting write concern options
84
+ # on initialization or at the time of an operation.
79
85
  #
80
86
  # @option opts [Integer] :cache_time (300) Set the time that all ensure_index calls should cache the command.
81
87
  #
@@ -88,12 +94,8 @@ module Mongo
88
94
 
89
95
  @write_concern = get_write_concern(opts, client)
90
96
 
91
- if value = opts[:read]
92
- Mongo::Support.validate_read_preference(value)
93
- else
94
- value = @connection.read_preference
95
- end
96
- @read_preference = value.is_a?(Hash) ? value.dup : value
97
+ @read = opts[:read] || @connection.read
98
+ Mongo::ReadPreference::validate(@read)
97
99
  @tag_sets = opts.fetch(:tag_sets, @connection.tag_sets)
98
100
  @acceptable_latency = opts.fetch(:acceptable_latency, @connection.acceptable_latency)
99
101
  @cache_time = opts[:cache_time] || 300 #5 minutes.
@@ -504,8 +506,11 @@ module Mongo
504
506
  # hashes are ordered by default.
505
507
  #
506
508
  # @option opts [Boolean] :check_response (true) If +true+, raises an exception if the
507
- # command fails.
509
+ # command fails.
508
510
  # @option opts [Socket] :socket a socket to use for sending the command. This is mainly for internal use.
511
+ # @option opts [:primary, :secondary] :read Read preference for this command. See Collection#find for
512
+ # more details.
513
+ # @option opts [String] :comment (nil) a comment to include in profiling logs
509
514
  #
510
515
  # @return [Hash]
511
516
  #
@@ -518,9 +523,20 @@ module Mongo
518
523
  raise MongoArgumentError, "DB#command requires an OrderedHash when hash contains multiple keys"
519
524
  end
520
525
 
526
+ if read_pref = opts[:read]
527
+ Mongo::ReadPreference::validate(read_pref)
528
+ unless read_pref == :primary || Mongo::Support::secondary_ok?(selector)
529
+ raise MongoArgumentError, "Command is not supported on secondaries: #{selector.keys.first}"
530
+ end
531
+ end
532
+
521
533
  begin
522
534
  result = Cursor.new(system_command_collection,
523
- :limit => -1, :selector => selector, :socket => socket).next_document
535
+ :limit => -1,
536
+ :selector => selector,
537
+ :socket => socket,
538
+ :read => read_pref,
539
+ :comment => opts[:comment]).next_document
524
540
  rescue OperationFailure => ex
525
541
  raise OperationFailure, "Database command '#{selector.keys.first}' failed: #{ex.message}"
526
542
  end
@@ -62,9 +62,11 @@ module Mongo
62
62
  # the content type will may be inferred from the filename extension if the mime-types gem can be
63
63
  # loaded. Otherwise, the content type 'binary/octet-stream' will be used.
64
64
  # @option opts [Integer] (262144) :chunk_size size of file chunks in bytes.
65
- # @option opts [Boolean] :w (1) Set the write concern
66
- # When :w > 0, the chunks sent to the server are validated using an md5 hash.
67
- # If validation fails, an exception will be raised.
65
+ # @option opts [String, Integer, Symbol] :w (1) Set write concern
66
+ #
67
+ # Notes on write concern:
68
+ # When :w > 0, the chunks sent to the server are validated using an md5 hash.
69
+ # If validation fails, an exception will be raised.
68
70
  #
69
71
  # @return [BSON::ObjectId] the file's id.
70
72
  def put(data, opts={})
@@ -69,9 +69,11 @@ module Mongo
69
69
  # @option opts [Boolean] :delete_old (false) ensure that old versions of the file are deleted. This option
70
70
  # only work in 'w' mode. Certain precautions must be taken when deleting GridFS files. See the notes under
71
71
  # GridFileSystem#delete.
72
- # @option opts [Hash] :w (1) Set the write concern
73
- # When :w > 0, the chunks sent to the server
74
- # will be validated using an md5 hash. If validation fails, an exception will be raised.
72
+ # @option opts [String, Integer, Symbol] :w (1) Set write concern
73
+ #
74
+ # Notes on write concern:
75
+ # When :w > 0, the chunks sent to the server
76
+ # will be validated using an md5 hash. If validation fails, an exception will be raised.
75
77
  # @option opts [Integer] :versions (false) deletes all versions which exceed the number specified to
76
78
  # retain ordered by uploadDate. This option only works in 'w' mode. Certain precautions must be taken when
77
79
  # deleting GridFS files. See the notes under GridFileSystem#delete.
@@ -50,9 +50,11 @@ module Mongo
50
50
  # @option opts [String] :content_type ('binary/octet-stream') If no content type is specified,
51
51
  # the content type will may be inferred from the filename extension if the mime-types gem can be
52
52
  # loaded. Otherwise, the content type 'binary/octet-stream' will be used.
53
- # @option opts [Hash] :w (1) Set the default write concern
54
- # When :w > 0, the chunks sent to the server
55
- # will be validated using an md5 hash. If validation fails, an exception will be raised.
53
+ # @option opts [String, Integer, Symbol] :w (1) Set the write concern
54
+ #
55
+ # Notes on write concern:
56
+ # When :w > 0, the chunks sent to the server
57
+ # will be validated using an md5 hash. If validation fails, an exception will be raised.
56
58
  def initialize(files, chunks, filename, mode, opts={})
57
59
  @files = files
58
60
  @chunks = chunks
@@ -43,16 +43,22 @@ end
43
43
 
44
44
  module Mongo
45
45
  # @deprecated Use Mongo::MongoClient instead. Support will be removed after v2.0
46
+ # Please see old documentation for the Connection class
46
47
  class Connection < MongoClient
47
48
  include Mongo::LegacyWriteConcern
48
49
 
49
- def initialize(host=nil, port=nil, opts={})
50
- write_concern_from_legacy(opts)
50
+ def initialize(*args)
51
+ if args.last.is_a?(Hash)
52
+ opts = args.pop
53
+ write_concern_from_legacy(opts)
54
+ args.push(opts)
55
+ end
51
56
  super
52
57
  end
53
58
  end
54
59
 
55
60
  # @deprecated Use Mongo::MongoReplicaSetClient instead. Support will be removed after v2.0
61
+ # Please see old documentation for the ReplSetConnection class
56
62
  class ReplSetConnection < MongoReplicaSetClient
57
63
  include Mongo::LegacyWriteConcern
58
64
 
@@ -67,6 +73,7 @@ module Mongo
67
73
  end
68
74
 
69
75
  # @deprecated Use Mongo::MongoShardedClient instead. Support will be removed after v2.0
76
+ # Please see old documentation for the ShardedConnection class
70
77
  class ShardedConnection < MongoShardedClient
71
78
  include Mongo::LegacyWriteConcern
72
79
 
@@ -28,18 +28,18 @@ module Mongo
28
28
  include Mongo::Networking
29
29
  include Mongo::WriteConcern
30
30
 
31
- TCPSocket = Mongo::TCPSocket
32
31
  Mutex = ::Mutex
33
32
  ConditionVariable = ::ConditionVariable
34
33
 
35
- DEFAULT_HOST = 'localhost'
36
- DEFAULT_PORT = 27017
37
- DEFAULT_DB_NAME = 'test'
38
- GENERIC_OPTS = [:ssl, :auths, :logger, :connect]
39
- TIMEOUT_OPTS = [:timeout, :op_timeout, :connect_timeout]
40
- POOL_OPTS = [:pool_size, :pool_timeout]
41
- WRITE_CONCERN_OPTS = [:w, :j, :fsync, :wtimeout]
42
- CLIENT_ONLY_OPTS = [:slave_ok]
34
+ DEFAULT_HOST = 'localhost'
35
+ DEFAULT_PORT = 27017
36
+ DEFAULT_DB_NAME = 'test'
37
+ GENERIC_OPTS = [:ssl, :auths, :logger, :connect]
38
+ TIMEOUT_OPTS = [:timeout, :op_timeout, :connect_timeout]
39
+ POOL_OPTS = [:pool_size, :pool_timeout]
40
+ READ_PREFERENCE_OPTS = [:read, :tag_sets, :secondary_acceptable_latency_ms]
41
+ WRITE_CONCERN_OPTS = [:w, :j, :fsync, :wtimeout]
42
+ CLIENT_ONLY_OPTS = [:slave_ok]
43
43
 
44
44
  mongo_thread_local_accessor :connections
45
45
 
@@ -56,7 +56,8 @@ module Mongo
56
56
  :socket_class,
57
57
  :op_timeout,
58
58
  :tag_sets,
59
- :acceptable_latency
59
+ :acceptable_latency,
60
+ :read
60
61
 
61
62
  # Create a connection to single MongoDB instance.
62
63
  #
@@ -72,13 +73,19 @@ module Mongo
72
73
  # MongoClient#arbiters. This is useful if your application needs to connect manually to nodes other
73
74
  # than the primary.
74
75
  #
75
- # @param [String, Hash] host
76
+ # @param [String] host
76
77
  # @param [Integer] port specify a port number here if only one host is being specified.
77
78
  #
78
- # @option opts [Hash] :w (1), :j (false), :wtimeout (false), :fsync (false) Set the default write concern
79
- # options propagated to DB objects instantiated off of this MongoClient.
80
- # This default can be overridden upon instantiation of any DB by explicitly setting an options hash
81
- # on initialization. It can also be overridden at instantiation of a collection or at the time of a write operation.
79
+ # @option opts [String, Integer, Symbol] :w (1) Set default number of nodes to which a write
80
+ # should be acknowledged
81
+ # @option opts [Boolean] :j (false) Set journal acknowledgement
82
+ # @option opts [Integer] :wtimeout (nil) Set replica set acknowledgement timeout
83
+ # @option opts [Boolean] :fsync (false) Set fsync acknowledgement.
84
+ #
85
+ # Notes about write concern options:
86
+ # Write concern options are propagated to objects instantiated from this MongoClient.
87
+ # These defaults can be overridden upon instantiation of any object by explicitly setting an options hash
88
+ # on initialization.
82
89
  # @option opts [Boolean] :slave_ok (false) Must be set to +true+ when connecting
83
90
  # to a single, slave node.
84
91
  # @option opts [Logger, #debug] :logger (nil) A Logger instance for debugging driver ops. Note that
@@ -106,6 +113,9 @@ module Mongo
106
113
  # @example localhost, 3000, where this node may be a slave
107
114
  # MongoClient.new("localhost", 3000, :slave_ok => true)
108
115
  #
116
+ # @example Unix Domain Socket
117
+ # MongoClient.new("/var/run/mongodb.sock")
118
+ #
109
119
  # @see http://api.mongodb.org/ruby/current/file.REPLICA_SETS.html Replica sets in Ruby
110
120
  #
111
121
  # @raise [ReplicaSetConnectionError] This is raised if a replica set name is specified and the
@@ -114,24 +124,9 @@ module Mongo
114
124
  # @raise [MongoArgumentError] If called with no arguments and <code>ENV["MONGODB_URI"]</code> implies a replica set.
115
125
  #
116
126
  # @core self.connections
117
- def initialize(host=nil, port=nil, opts={})
118
- if host.nil? and ENV.has_key?('MONGODB_URI')
119
- parser = URIParser.new ENV['MONGODB_URI']
120
- if parser.replicaset?
121
- raise MongoArgumentError, "Mongo::MongoClient.new called with no arguments, but ENV['MONGODB_URI'] implies a replica set."
122
- end
123
- opts.merge!(parser.connection_options)
124
- @host_to_try = [parser.host, parser.port]
125
- elsif host.is_a?(String) && (port || DEFAULT_PORT).respond_to?(:to_i)
126
- @host_to_try = [host, (port || DEFAULT_PORT).to_i]
127
- elsif host || port
128
- raise MongoArgumentError, "Mongo::MongoClient.new host or port argument error, host:#{host.inspect}, port:#{port.inspect}"
129
- else
130
- @host_to_try = [DEFAULT_HOST, DEFAULT_PORT]
131
- end
132
-
133
- # Host and port of current master.
134
- @host = @port = nil
127
+ def initialize(*args)
128
+ opts = args.last.is_a?(Hash) ? args.pop : {}
129
+ @host, @port = parse_init(args[0], args[1], opts)
135
130
 
136
131
  # Default maximum BSON object size
137
132
  @max_bson_size = Mongo::DEFAULT_MAX_BSON_SIZE
@@ -139,16 +134,17 @@ module Mongo
139
134
  # Lock for request ids.
140
135
  @id_lock = Mutex.new
141
136
 
142
- # Connection pool for primay node
137
+ # Connection pool for primary node
143
138
  @primary = nil
144
139
  @primary_pool = nil
140
+ @mongos = false
145
141
 
146
142
  # Not set for direct connection
147
- @tag_sets = {}
143
+ @tag_sets = []
148
144
  @acceptable_latency = 15
149
145
 
150
146
  check_opts(opts)
151
- setup(opts)
147
+ setup(opts.dup)
152
148
  end
153
149
 
154
150
  # DEPRECATED
@@ -180,12 +176,12 @@ module Mongo
180
176
  def self.multi(nodes, opts={})
181
177
  warn "MongoClient.multi is now deprecated and will be removed in v2.0. Please use MongoReplicaSetClient.new instead."
182
178
 
183
- MongoReplicaSetClient.new(*(nodes+[opts]))
179
+ MongoReplicaSetClient.new(nodes, opts)
184
180
  end
185
181
 
186
182
  # Initialize a connection to MongoDB using the MongoDB URI spec.
187
183
  #
188
- # Since MongoClient.new cannot be used with any <code>ENV["MONGODB_URI"]</code> that has multiple hosts (implying a replicaset),
184
+ # Since MongoClient.new cannot be used with any <code>ENV["MONGODB_URI"]</code> that has multiple hosts (implying a replicaset),
189
185
  # you may use this when the type of your connection varies by environment and should be determined solely from <code>ENV["MONGODB_URI"]</code>.
190
186
  #
191
187
  # @param uri [String]
@@ -199,6 +195,20 @@ module Mongo
199
195
  parser.connection(extra_opts)
200
196
  end
201
197
 
198
+ def parse_init(host, port, opts)
199
+ if host.nil? && port.nil? && ENV.has_key?('MONGODB_URI')
200
+ parser = URIParser.new(ENV['MONGODB_URI'])
201
+ if parser.replicaset?
202
+ raise MongoArgumentError,
203
+ "ENV['MONGODB_URI'] implies a replica set."
204
+ end
205
+ opts.merge! parser.connection_options
206
+ [parser.host, parser.port]
207
+ else
208
+ [host || DEFAULT_HOST, port || DEFAULT_PORT]
209
+ end
210
+ end
211
+
202
212
  # The host name used for this connection.
203
213
  #
204
214
  # @return [String]
@@ -213,6 +223,10 @@ module Mongo
213
223
  @primary_pool.port
214
224
  end
215
225
 
226
+ def host_port
227
+ [@host, @port]
228
+ end
229
+
216
230
  # Fsync, then lock the mongod process against writes. Use this to get
217
231
  # the datafiles in a state safe for snapshotting, backing up, etc.
218
232
  #
@@ -415,7 +429,6 @@ module Mongo
415
429
  self["admin"].command({:buildinfo => 1})
416
430
  end
417
431
 
418
-
419
432
  # Get the build version of the current server.
420
433
  #
421
434
  # @return [Mongo::ServerVersion]
@@ -431,6 +444,10 @@ module Mongo
431
444
  @slave_ok
432
445
  end
433
446
 
447
+ def mongos?
448
+ @mongos
449
+ end
450
+
434
451
  # Create a new socket and attempt to connect to master.
435
452
  # If successful, sets host and port to master and returns the socket.
436
453
  #
@@ -441,7 +458,8 @@ module Mongo
441
458
  def connect
442
459
  close
443
460
 
444
- config = check_is_master(@host_to_try)
461
+ config = check_is_master(host_port)
462
+
445
463
  if config
446
464
  if config['ismaster'] == 1 || config['ismaster'] == true
447
465
  @read_primary = true
@@ -449,15 +467,22 @@ module Mongo
449
467
  @read_primary = false
450
468
  end
451
469
 
470
+ if config.has_key?('msg') && config['msg'] == 'isdbgrid'
471
+ @mongos = true
472
+ end
473
+
452
474
  @max_bson_size = config['maxBsonObjectSize'] || Mongo::DEFAULT_MAX_BSON_SIZE
453
- set_primary(@host_to_try)
475
+ set_primary(host_port)
454
476
  end
455
477
 
456
478
  if !connected?
457
- raise ConnectionFailure, "Failed to connect to a master node at #{@host_to_try[0]}:#{@host_to_try[1]}"
479
+ raise ConnectionFailure, "Failed to connect to a master node at #{host_port.join(":")}"
458
480
  end
459
481
  end
460
- alias :reconnect :connect
482
+
483
+ # Ensures that the alias carries over to the overridden connect method when using
484
+ # the replica set or sharded clients.
485
+ def reconnect; connect end
461
486
 
462
487
  # It's possible that we defined connected as all nodes being connected???
463
488
  # NOTE: Do check if this needs to be more stringent.
@@ -489,7 +514,10 @@ module Mongo
489
514
  def read_primary?
490
515
  @read_primary
491
516
  end
492
- alias :primary? :read_primary?
517
+
518
+ # Ensures that the alias carries over to the overridden connect method when using
519
+ # the replica set or sharded clients.
520
+ def primary?; read_primary? end
493
521
 
494
522
  # The socket pool that this connection reads from.
495
523
  #
@@ -498,15 +526,6 @@ module Mongo
498
526
  @primary_pool
499
527
  end
500
528
 
501
- # The value of the read preference.
502
- def read_preference
503
- if slave_ok?
504
- :secondary_preferred
505
- else
506
- :primary
507
- end
508
- end
509
-
510
529
  # Close the connection to the database.
511
530
  def close
512
531
  @primary_pool.close if @primary_pool
@@ -550,6 +569,7 @@ module Mongo
550
569
  GENERIC_OPTS +
551
570
  CLIENT_ONLY_OPTS +
552
571
  POOL_OPTS +
572
+ READ_PREFERENCE_OPTS +
553
573
  WRITE_CONCERN_OPTS +
554
574
  TIMEOUT_OPTS
555
575
  end
@@ -564,13 +584,15 @@ module Mongo
564
584
 
565
585
  # Parse option hash
566
586
  def setup(opts)
567
- # slave_ok can be true only if one node is specified
568
587
  @slave_ok = opts.delete(:slave_ok)
569
588
 
570
- # Determine whether to use SSL.
571
589
  @ssl = opts.delete(:ssl)
590
+ @unix = @host ? @host.end_with?('.sock') : false
591
+
572
592
  if @ssl
573
593
  @socket_class = Mongo::SSLSocket
594
+ elsif @unix
595
+ @socket_class = Mongo::UNIXSocket
574
596
  else
575
597
  @socket_class = Mongo::TCPSocket
576
598
  end
@@ -590,41 +612,47 @@ module Mongo
590
612
  @op_timeout = opts.delete(:op_timeout) || nil
591
613
 
592
614
  # Timeout on socket connect.
593
- @connect_timeout = opts.delete(:connect_timeout) || nil
615
+ @connect_timeout = opts.delete(:connect_timeout) || 30
594
616
 
595
- @logger = opts.fetch(:logger, nil)
596
-
597
- # Connection level write concern options.
598
- @write_concern = get_write_concern(opts)
617
+ @logger = opts.delete(:logger) || nil
599
618
 
600
619
  if @logger
601
620
  write_logging_startup_message
602
621
  end
603
622
 
604
- if opts.fetch(:connect, true)
605
- connect
623
+ # Determine read preference
624
+ if defined?(@slave_ok) && (@slave_ok) || defined?(@read_secondary) && @read_secondary
625
+ @read = :secondary_preferred
626
+ else
627
+ @read = opts.delete(:read) || :primary
606
628
  end
607
- end
629
+ Mongo::ReadPreference::validate(@read)
608
630
 
609
- private
631
+ @tag_sets = opts.delete(:tag_sets) || []
632
+ @acceptable_latency = opts.delete(:secondary_acceptable_latency_ms) || 15
610
633
 
611
- ## Methods for establishing a connection:
634
+ # Connection level write concern options.
635
+ @write_concern = get_write_concern(opts)
612
636
 
613
- # If a ConnectionFailure is raised, this method will be called
614
- # to close the connection and reset connection values.
615
- # TODO: evaluate whether this method is actually necessary
616
- def reset_connection
617
- close
637
+ connect if opts.fetch(:connect, true)
618
638
  end
619
639
 
640
+ private
641
+
620
642
  def check_is_master(node)
621
643
  begin
622
644
  host, port = *node
623
645
  socket = nil
624
646
  config = nil
625
647
 
626
- socket = @socket_class.new(host, port, @op_timeout, @connect_timeout)
627
- config = self['admin'].command({:ismaster => 1}, :socket => socket)
648
+ socket = @socket_class.new(host, port, @op_timeout, @connect_timeout)
649
+ if(@connect_timeout)
650
+ Timeout::timeout(@connect_timeout, OperationTimeout) do
651
+ config = self['admin'].command({:ismaster => 1}, :socket => socket)
652
+ end
653
+ else
654
+ config = self['admin'].command({:ismaster => 1}, :socket => socket)
655
+ end
628
656
  rescue OperationFailure, SocketError, SystemCallError, IOError
629
657
  close
630
658
  ensure