mongo 1.7.1 → 1.8.0
Sign up to get free protection for your applications and to get access to all the features.
- data/{LICENSE.txt → LICENSE} +0 -0
- data/README.md +124 -111
- data/Rakefile +9 -325
- data/VERSION +1 -0
- data/bin/mongo_console +4 -4
- data/examples/admin.rb +43 -0
- data/examples/capped.rb +22 -0
- data/examples/cursor.rb +48 -0
- data/examples/gridfs.rb +44 -0
- data/examples/index_test.rb +126 -0
- data/examples/info.rb +31 -0
- data/examples/queries.rb +74 -0
- data/examples/replica_set.rb +26 -0
- data/examples/simple.rb +25 -0
- data/examples/strict.rb +35 -0
- data/examples/types.rb +36 -0
- data/{test/load → examples/web}/thin/load.rb +3 -1
- data/{test/load → examples/web}/unicorn/load.rb +5 -3
- data/lib/mongo.rb +8 -10
- data/lib/mongo/collection.rb +134 -114
- data/lib/mongo/cursor.rb +21 -14
- data/lib/mongo/db.rb +30 -28
- data/lib/mongo/exceptions.rb +1 -1
- data/lib/mongo/gridfs/grid.rb +8 -7
- data/lib/mongo/gridfs/grid_ext.rb +1 -1
- data/lib/mongo/gridfs/grid_file_system.rb +6 -5
- data/lib/mongo/gridfs/grid_io.rb +22 -19
- data/lib/mongo/legacy.rb +82 -0
- data/lib/mongo/{connection.rb → mongo_client.rb} +82 -61
- data/lib/mongo/{repl_set_connection.rb → mongo_replica_set_client.rb} +54 -39
- data/lib/mongo/{sharded_connection.rb → mongo_sharded_client.rb} +9 -9
- data/lib/mongo/networking.rb +25 -20
- data/lib/mongo/util/conversions.rb +1 -1
- data/lib/mongo/util/core_ext.rb +1 -1
- data/lib/mongo/util/logging.rb +20 -4
- data/lib/mongo/util/node.rb +16 -16
- data/lib/mongo/util/pool.rb +56 -27
- data/lib/mongo/util/pool_manager.rb +28 -27
- data/lib/mongo/util/server_version.rb +1 -1
- data/lib/mongo/util/sharding_pool_manager.rb +8 -8
- data/lib/mongo/util/ssl_socket.rb +1 -5
- data/lib/mongo/util/support.rb +24 -8
- data/lib/mongo/util/tcp_socket.rb +0 -4
- data/lib/mongo/util/uri_parser.rb +54 -38
- data/lib/mongo/util/write_concern.rb +67 -0
- data/mongo.gemspec +21 -32
- data/test/auxillary/{1.4_features.rb → 1.4_feature_test.rb} +4 -5
- data/test/auxillary/authentication_test.rb +18 -20
- data/test/auxillary/autoreconnect_test.rb +3 -5
- data/test/auxillary/fork_test.rb +5 -7
- data/test/auxillary/repl_set_auth_test.rb +13 -15
- data/test/auxillary/slave_connection_test.rb +8 -7
- data/test/auxillary/threaded_authentication_test.rb +15 -17
- data/test/bson/binary_test.rb +1 -1
- data/test/bson/bson_test.rb +60 -36
- data/test/bson/byte_buffer_test.rb +1 -1
- data/test/bson/hash_with_indifferent_access_test.rb +2 -2
- data/test/bson/json_test.rb +1 -2
- data/test/bson/object_id_test.rb +1 -2
- data/test/bson/ordered_hash_test.rb +1 -1
- data/test/bson/timestamp_test.rb +1 -1
- data/test/{collection_test.rb → functional/collection_test.rb} +57 -57
- data/test/{connection_test.rb → functional/connection_test.rb} +75 -89
- data/test/{conversions_test.rb → functional/conversions_test.rb} +1 -1
- data/test/{cursor_fail_test.rb → functional/cursor_fail_test.rb} +3 -29
- data/test/{cursor_message_test.rb → functional/cursor_message_test.rb} +1 -1
- data/test/{cursor_test.rb → functional/cursor_test.rb} +5 -1
- data/test/{db_api_test.rb → functional/db_api_test.rb} +8 -9
- data/test/{db_connection_test.rb → functional/db_connection_test.rb} +3 -5
- data/test/{db_test.rb → functional/db_test.rb} +13 -13
- data/test/{grid_file_system_test.rb → functional/grid_file_system_test.rb} +2 -2
- data/test/{grid_io_test.rb → functional/grid_io_test.rb} +6 -6
- data/test/{grid_test.rb → functional/grid_test.rb} +4 -10
- data/test/{pool_test.rb → functional/pool_test.rb} +1 -1
- data/test/functional/safe_test.rb +84 -0
- data/test/{support_test.rb → functional/support_test.rb} +1 -1
- data/test/{threading_test.rb → functional/threading_test.rb} +9 -9
- data/test/{timeout_test.rb → functional/timeout_test.rb} +1 -1
- data/test/{uri_test.rb → functional/uri_test.rb} +1 -1
- data/test/functional/write_concern_test.rb +104 -0
- data/test/replica_set/basic_test.rb +139 -0
- data/test/replica_set/client_test.rb +255 -0
- data/test/replica_set/complex_connect_test.rb +62 -0
- data/test/replica_set/connection_test.rb +255 -0
- data/test/{replica_sets → replica_set}/count_test.rb +17 -14
- data/test/replica_set/cursor_test.rb +75 -0
- data/test/{replica_sets → replica_set}/insert_test.rb +19 -16
- data/test/replica_set/query_test.rb +64 -0
- data/test/replica_set/refresh_test.rb +153 -0
- data/test/{replica_sets → replica_set}/replication_ack_test.rb +21 -17
- data/test/sharded_cluster/basic_test.rb +31 -50
- data/test/support/hash_with_indifferent_access.rb +1 -1
- data/test/test_helper.rb +56 -9
- data/test/threading/threading_with_large_pool_test.rb +8 -8
- data/test/tools/mongo_config.rb +270 -58
- data/test/tools/mongo_config_test.rb +146 -0
- data/test/unit/client_test.rb +230 -0
- data/test/unit/collection_test.rb +45 -32
- data/test/unit/connection_test.rb +82 -74
- data/test/unit/cursor_test.rb +14 -6
- data/test/unit/db_test.rb +8 -8
- data/test/unit/grid_test.rb +11 -11
- data/test/unit/node_test.rb +24 -24
- data/test/unit/pool_manager_test.rb +13 -13
- data/test/unit/pool_test.rb +1 -1
- data/test/unit/read_test.rb +21 -26
- data/test/unit/safe_test.rb +52 -33
- data/test/unit/util_test.rb +55 -0
- data/test/unit/write_concern_test.rb +161 -0
- metadata +158 -171
- data/docs/CREDITS.md +0 -123
- data/docs/FAQ.md +0 -116
- data/docs/GRID_FS.md +0 -158
- data/docs/HISTORY.md +0 -392
- data/docs/READ_PREFERENCE.md +0 -99
- data/docs/RELEASES.md +0 -54
- data/docs/REPLICA_SETS.md +0 -113
- data/docs/TAILABLE_CURSORS.md +0 -51
- data/docs/TUTORIAL.md +0 -356
- data/docs/WRITE_CONCERN.md +0 -31
- data/lib/mongo/gridfs/grid_io_fix.rb +0 -38
- data/lib/mongo/version.rb +0 -3
- data/test/bson/test_helper.rb +0 -30
- data/test/replica_sets/basic_test.rb +0 -119
- data/test/replica_sets/complex_connect_test.rb +0 -57
- data/test/replica_sets/complex_read_preference_test.rb +0 -237
- data/test/replica_sets/connect_test.rb +0 -156
- data/test/replica_sets/cursor_test.rb +0 -70
- data/test/replica_sets/pooled_insert_test.rb +0 -57
- data/test/replica_sets/query_test.rb +0 -50
- data/test/replica_sets/read_preference_test.rb +0 -234
- data/test/replica_sets/refresh_test.rb +0 -156
- data/test/replica_sets/refresh_with_threads_test.rb +0 -60
- data/test/replica_sets/rs_test_helper.rb +0 -39
- data/test/safe_test.rb +0 -68
- data/test/sharded_cluster/mongo_config_test.rb +0 -126
- data/test/sharded_cluster/sc_test_helper.rb +0 -39
- data/test/tools/repl_set_manager.rb +0 -418
data/lib/mongo/legacy.rb
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
# --
|
4
|
+
# Copyright (C) 2008-2012 10gen Inc.
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
# ++
|
18
|
+
|
19
|
+
module Mongo
|
20
|
+
module LegacyWriteConcern
|
21
|
+
@legacy_write_concern = true
|
22
|
+
|
23
|
+
def safe=(value)
|
24
|
+
@write_concern = value
|
25
|
+
end
|
26
|
+
|
27
|
+
def safe
|
28
|
+
if @write_concern[:w] == 0
|
29
|
+
return false
|
30
|
+
elsif @write_concern[:w] == 1
|
31
|
+
return true
|
32
|
+
else
|
33
|
+
return @write_concern
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.from_uri(uri = ENV['MONGODB_URI'], extra_opts={})
|
38
|
+
parser = URIParser.new uri
|
39
|
+
parser.connection(extra_opts, true)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
module Mongo
|
45
|
+
# @deprecated Use Mongo::MongoClient instead. Support will be removed after v2.0
|
46
|
+
class Connection < MongoClient
|
47
|
+
include Mongo::LegacyWriteConcern
|
48
|
+
|
49
|
+
def initialize(host=nil, port=nil, opts={})
|
50
|
+
write_concern_from_legacy(opts)
|
51
|
+
super
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# @deprecated Use Mongo::MongoReplicaSetClient instead. Support will be removed after v2.0
|
56
|
+
class ReplSetConnection < MongoReplicaSetClient
|
57
|
+
include Mongo::LegacyWriteConcern
|
58
|
+
|
59
|
+
def initialize(*args)
|
60
|
+
if args.last.is_a?(Hash)
|
61
|
+
opts = args.pop
|
62
|
+
write_concern_from_legacy(opts)
|
63
|
+
args.push(opts)
|
64
|
+
end
|
65
|
+
super
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# @deprecated Use Mongo::MongoShardedClient instead. Support will be removed after v2.0
|
70
|
+
class ShardedConnection < MongoShardedClient
|
71
|
+
include Mongo::LegacyWriteConcern
|
72
|
+
|
73
|
+
def initialize(*args)
|
74
|
+
if args.last.is_a?(Hash)
|
75
|
+
opts = args.pop
|
76
|
+
write_concern_from_legacy(opts)
|
77
|
+
args.push(opts)
|
78
|
+
end
|
79
|
+
super
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
|
3
3
|
# --
|
4
|
-
# Copyright (C) 2008-
|
4
|
+
# Copyright (C) 2008-2012 10gen Inc.
|
5
5
|
#
|
6
6
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
7
|
# you may not use this file except in compliance with the License.
|
@@ -19,30 +19,44 @@
|
|
19
19
|
require 'set'
|
20
20
|
require 'socket'
|
21
21
|
require 'thread'
|
22
|
+
|
22
23
|
module Mongo
|
23
24
|
|
24
25
|
# Instantiates and manages self.connections to MongoDB.
|
25
|
-
class
|
26
|
+
class MongoClient
|
26
27
|
include Mongo::Logging
|
27
28
|
include Mongo::Networking
|
29
|
+
include Mongo::WriteConcern
|
28
30
|
|
29
|
-
TCPSocket
|
30
|
-
Mutex
|
31
|
-
ConditionVariable
|
32
|
-
|
33
|
-
Thread.abort_on_exception = true
|
31
|
+
TCPSocket = Mongo::TCPSocket
|
32
|
+
Mutex = ::Mutex
|
33
|
+
ConditionVariable = ::ConditionVariable
|
34
34
|
|
35
|
-
DEFAULT_HOST
|
36
|
-
DEFAULT_PORT
|
37
|
-
DEFAULT_DB_NAME
|
38
|
-
GENERIC_OPTS
|
39
|
-
|
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]
|
40
43
|
|
41
44
|
mongo_thread_local_accessor :connections
|
42
45
|
|
43
|
-
attr_reader :logger,
|
44
|
-
|
45
|
-
|
46
|
+
attr_reader :logger,
|
47
|
+
:size,
|
48
|
+
:auths,
|
49
|
+
:primary,
|
50
|
+
:write_concern,
|
51
|
+
:host_to_try,
|
52
|
+
:pool_size,
|
53
|
+
:connect_timeout,
|
54
|
+
:pool_timeout,
|
55
|
+
:primary_pool,
|
56
|
+
:socket_class,
|
57
|
+
:op_timeout,
|
58
|
+
:tag_sets,
|
59
|
+
:acceptable_latency
|
46
60
|
|
47
61
|
# Create a connection to single MongoDB instance.
|
48
62
|
#
|
@@ -51,20 +65,20 @@ module Mongo
|
|
51
65
|
# You may specify whether connection to slave is permitted.
|
52
66
|
# In all cases, the default host is "localhost" and the default port is 27017.
|
53
67
|
#
|
54
|
-
# If you're connecting to a replica set, you'll need to use
|
68
|
+
# If you're connecting to a replica set, you'll need to use MongoReplicaSetClient.new instead.
|
55
69
|
#
|
56
70
|
# Once connected to a replica set, you can find out which nodes are primary, secondary, and
|
57
|
-
# arbiters with the corresponding accessors:
|
58
|
-
#
|
71
|
+
# arbiters with the corresponding accessors: MongoClient#primary, MongoClient#secondaries, and
|
72
|
+
# MongoClient#arbiters. This is useful if your application needs to connect manually to nodes other
|
59
73
|
# than the primary.
|
60
74
|
#
|
61
75
|
# @param [String, Hash] host
|
62
76
|
# @param [Integer] port specify a port number here if only one host is being specified.
|
63
77
|
#
|
64
|
-
# @option opts [
|
65
|
-
#
|
66
|
-
# default can be overridden upon instantiation of any DB by
|
67
|
-
# on initialization.
|
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.
|
68
82
|
# @option opts [Boolean] :slave_ok (false) Must be set to +true+ when connecting
|
69
83
|
# to a single, slave node.
|
70
84
|
# @option opts [Logger, #debug] :logger (nil) A Logger instance for debugging driver ops. Note that
|
@@ -81,16 +95,16 @@ module Mongo
|
|
81
95
|
# @option opts [Boolean] :ssl (false) If true, create the connection to the server using SSL.
|
82
96
|
#
|
83
97
|
# @example localhost, 27017 (or <code>ENV["MONGODB_URI"]</code> if available)
|
84
|
-
#
|
98
|
+
# MongoClient.new
|
85
99
|
#
|
86
100
|
# @example localhost, 27017
|
87
|
-
#
|
101
|
+
# MongoClient.new("localhost")
|
88
102
|
#
|
89
103
|
# @example localhost, 3000, max 5 self.connections, with max 5 seconds of wait time.
|
90
|
-
#
|
104
|
+
# MongoClient.new("localhost", 3000, :pool_size => 5, :timeout => 5)
|
91
105
|
#
|
92
106
|
# @example localhost, 3000, where this node may be a slave
|
93
|
-
#
|
107
|
+
# MongoClient.new("localhost", 3000, :slave_ok => true)
|
94
108
|
#
|
95
109
|
# @see http://api.mongodb.org/ruby/current/file.REPLICA_SETS.html Replica sets in Ruby
|
96
110
|
#
|
@@ -104,25 +118,27 @@ module Mongo
|
|
104
118
|
if host.nil? and ENV.has_key?('MONGODB_URI')
|
105
119
|
parser = URIParser.new ENV['MONGODB_URI']
|
106
120
|
if parser.replicaset?
|
107
|
-
raise MongoArgumentError, "Mongo::
|
121
|
+
raise MongoArgumentError, "Mongo::MongoClient.new called with no arguments, but ENV['MONGODB_URI'] implies a replica set."
|
108
122
|
end
|
109
|
-
opts
|
123
|
+
opts.merge!(parser.connection_options)
|
110
124
|
@host_to_try = [parser.host, parser.port]
|
111
|
-
elsif host.is_a?(String)
|
125
|
+
elsif host.is_a?(String) && (port || DEFAULT_PORT).respond_to?(:to_i)
|
112
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}"
|
113
129
|
else
|
114
130
|
@host_to_try = [DEFAULT_HOST, DEFAULT_PORT]
|
115
131
|
end
|
116
132
|
|
117
133
|
# Host and port of current master.
|
118
134
|
@host = @port = nil
|
119
|
-
|
135
|
+
|
120
136
|
# Default maximum BSON object size
|
121
137
|
@max_bson_size = Mongo::DEFAULT_MAX_BSON_SIZE
|
122
|
-
|
138
|
+
|
123
139
|
# Lock for request ids.
|
124
140
|
@id_lock = Mutex.new
|
125
|
-
|
141
|
+
|
126
142
|
# Connection pool for primay node
|
127
143
|
@primary = nil
|
128
144
|
@primary_pool = nil
|
@@ -140,11 +156,11 @@ module Mongo
|
|
140
156
|
# Initialize a connection to a MongoDB replica set using an array of seed nodes.
|
141
157
|
#
|
142
158
|
# The seed nodes specified will be used on the initial connection to the replica set, but note
|
143
|
-
# that this list of nodes will be
|
159
|
+
# that this list of nodes will be replaced by the list of canonical nodes returned by running the
|
144
160
|
# is_master command on the replica set.
|
145
161
|
#
|
146
162
|
# @param nodes [Array] An array of arrays, each of which specifies a host and port.
|
147
|
-
# @param opts [Hash] Any of the available options that can be passed to
|
163
|
+
# @param opts [Hash] Any of the available options that can be passed to MongoClient.new.
|
148
164
|
#
|
149
165
|
# @option opts [String] :rs_name (nil) The name of the replica set to connect to. An exception will be
|
150
166
|
# raised if unable to connect to a replica set with this name.
|
@@ -152,31 +168,32 @@ module Mongo
|
|
152
168
|
# to send reads to.
|
153
169
|
#
|
154
170
|
# @example
|
155
|
-
# Mongo::
|
171
|
+
# Mongo::MongoClient.multi([["db1.example.com", 27017], ["db2.example.com", 27017]])
|
156
172
|
#
|
157
173
|
# @example This connection will read from a random secondary node.
|
158
|
-
# Mongo::
|
174
|
+
# Mongo::MongoClient.multi([["db1.example.com", 27017], ["db2.example.com", 27017], ["db3.example.com", 27017]],
|
159
175
|
# :read_secondary => true)
|
160
176
|
#
|
161
|
-
# @return [Mongo::
|
177
|
+
# @return [Mongo::MongoClient]
|
162
178
|
#
|
163
179
|
# @deprecated
|
164
180
|
def self.multi(nodes, opts={})
|
165
|
-
warn "
|
181
|
+
warn "MongoClient.multi is now deprecated and will be removed in v2.0. Please use MongoReplicaSetClient.new instead."
|
166
182
|
|
167
|
-
|
183
|
+
MongoReplicaSetClient.new(*(nodes+[opts]))
|
168
184
|
end
|
169
185
|
|
170
186
|
# Initialize a connection to MongoDB using the MongoDB URI spec.
|
171
187
|
#
|
172
|
-
# Since
|
188
|
+
# Since MongoClient.new cannot be used with any <code>ENV["MONGODB_URI"]</code> that has multiple hosts (implying a replicaset),
|
189
|
+
# you may use this when the type of your connection varies by environment and should be determined solely from <code>ENV["MONGODB_URI"]</code>.
|
173
190
|
#
|
174
191
|
# @param uri [String]
|
175
192
|
# A string of the format mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/database]
|
176
193
|
#
|
177
|
-
# @param opts Any of the options available for
|
194
|
+
# @param opts Any of the options available for MongoClient.new
|
178
195
|
#
|
179
|
-
# @return [Mongo::
|
196
|
+
# @return [Mongo::MongoClient, Mongo::MongoReplicaSetClient]
|
180
197
|
def self.from_uri(uri = ENV['MONGODB_URI'], extra_opts={})
|
181
198
|
parser = URIParser.new uri
|
182
199
|
parser.connection(extra_opts)
|
@@ -223,7 +240,7 @@ module Mongo
|
|
223
240
|
|
224
241
|
# Apply each of the saved database authentications.
|
225
242
|
#
|
226
|
-
# @return [Boolean] returns true if authentications exist and
|
243
|
+
# @return [Boolean] returns true if authentications exist and succeeds, false
|
227
244
|
# if none exists.
|
228
245
|
#
|
229
246
|
# @raise [AuthenticationError] raises an exception if any one
|
@@ -239,11 +256,11 @@ module Mongo
|
|
239
256
|
|
240
257
|
# Save an authentication to this connection. When connecting,
|
241
258
|
# the connection will attempt to re-authenticate on every db
|
242
|
-
#
|
259
|
+
# specified in the list of auths. This method is called automatically
|
243
260
|
# by DB#authenticate.
|
244
261
|
#
|
245
262
|
# Note: this method will not actually issue an authentication command. To do that,
|
246
|
-
# either run
|
263
|
+
# either run MongoClient#apply_saved_authentication or DB#authenticate.
|
247
264
|
#
|
248
265
|
# @param [String] db_name
|
249
266
|
# @param [String] username
|
@@ -274,7 +291,7 @@ module Mongo
|
|
274
291
|
end
|
275
292
|
end
|
276
293
|
|
277
|
-
# Remove all
|
294
|
+
# Remove all authentication information stored in this connection.
|
278
295
|
#
|
279
296
|
# @return [true] this operation return true because it always succeeds.
|
280
297
|
def clear_auths
|
@@ -506,21 +523,21 @@ module Mongo
|
|
506
523
|
end
|
507
524
|
|
508
525
|
# Checkout a socket for reading (i.e., a secondary node).
|
509
|
-
# Note: this is overridden in
|
526
|
+
# Note: this is overridden in MongoReplicaSetClient.
|
510
527
|
def checkout_reader(mode=:primary, tag_sets={}, acceptable_latency=15)
|
511
528
|
connect unless connected?
|
512
529
|
@primary_pool.checkout
|
513
530
|
end
|
514
531
|
|
515
532
|
# Checkout a socket for writing (i.e., a primary node).
|
516
|
-
# Note: this is overridden in
|
533
|
+
# Note: this is overridden in MongoReplicaSetClient.
|
517
534
|
def checkout_writer
|
518
535
|
connect unless connected?
|
519
536
|
@primary_pool.checkout
|
520
537
|
end
|
521
538
|
|
522
539
|
# Check a socket back into its pool.
|
523
|
-
# Note: this is overridden in
|
540
|
+
# Note: this is overridden in MongoReplicaSetClient.
|
524
541
|
def checkin(socket)
|
525
542
|
if @primary_pool && socket && socket.pool
|
526
543
|
socket.pool.checkin(socket)
|
@@ -530,7 +547,11 @@ module Mongo
|
|
530
547
|
protected
|
531
548
|
|
532
549
|
def valid_opts
|
533
|
-
GENERIC_OPTS +
|
550
|
+
GENERIC_OPTS +
|
551
|
+
CLIENT_ONLY_OPTS +
|
552
|
+
POOL_OPTS +
|
553
|
+
WRITE_CONCERN_OPTS +
|
554
|
+
TIMEOUT_OPTS
|
534
555
|
end
|
535
556
|
|
536
557
|
def check_opts(opts)
|
@@ -544,10 +565,10 @@ module Mongo
|
|
544
565
|
# Parse option hash
|
545
566
|
def setup(opts)
|
546
567
|
# slave_ok can be true only if one node is specified
|
547
|
-
@slave_ok = opts
|
548
|
-
|
568
|
+
@slave_ok = opts.delete(:slave_ok)
|
569
|
+
|
549
570
|
# Determine whether to use SSL.
|
550
|
-
@ssl = opts.
|
571
|
+
@ssl = opts.delete(:ssl)
|
551
572
|
if @ssl
|
552
573
|
@socket_class = Mongo::SSLSocket
|
553
574
|
else
|
@@ -555,27 +576,27 @@ module Mongo
|
|
555
576
|
end
|
556
577
|
|
557
578
|
# Authentication objects
|
558
|
-
@auths = opts.
|
579
|
+
@auths = opts.delete(:auths) || []
|
559
580
|
|
560
581
|
# Pool size and timeout.
|
561
|
-
@pool_size = opts
|
582
|
+
@pool_size = opts.delete(:pool_size) || 1
|
562
583
|
if opts[:timeout]
|
563
584
|
warn "The :timeout option has been deprecated " +
|
564
585
|
"and will be removed in the 2.0 release. Use :pool_timeout instead."
|
565
586
|
end
|
566
|
-
@pool_timeout = opts
|
587
|
+
@pool_timeout = opts.delete(:pool_timeout) || opts.delete(:timeout) || 5.0
|
567
588
|
|
568
589
|
# Timeout on socket read operation.
|
569
|
-
@op_timeout = opts
|
590
|
+
@op_timeout = opts.delete(:op_timeout) || nil
|
570
591
|
|
571
592
|
# Timeout on socket connect.
|
572
|
-
@connect_timeout = opts
|
573
|
-
|
574
|
-
# Global safe option. This is false by default.
|
575
|
-
@safe = opts[:safe] || false
|
593
|
+
@connect_timeout = opts.delete(:connect_timeout) || nil
|
576
594
|
|
577
595
|
@logger = opts.fetch(:logger, nil)
|
578
596
|
|
597
|
+
# Connection level write concern options.
|
598
|
+
@write_concern = get_write_concern(opts)
|
599
|
+
|
579
600
|
if @logger
|
580
601
|
write_logging_startup_message
|
581
602
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
|
3
3
|
# --
|
4
|
-
# Copyright (C) 2008-
|
4
|
+
# Copyright (C) 2008-2012 10gen Inc.
|
5
5
|
#
|
6
6
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
7
|
# you may not use this file except in compliance with the License.
|
@@ -19,29 +19,43 @@
|
|
19
19
|
module Mongo
|
20
20
|
|
21
21
|
# Instantiates and manages connections to a MongoDB replica set.
|
22
|
-
class
|
23
|
-
|
24
|
-
REPL_SET_OPTS = [
|
25
|
-
:
|
26
|
-
|
27
|
-
|
28
|
-
:
|
22
|
+
class MongoReplicaSetClient < MongoClient
|
23
|
+
|
24
|
+
REPL_SET_OPTS = [
|
25
|
+
:read,
|
26
|
+
:refresh_mode,
|
27
|
+
:refresh_interval,
|
28
|
+
:read_secondary,
|
29
|
+
:rs_name,
|
30
|
+
:name,
|
31
|
+
:tag_sets,
|
32
|
+
:secondary_acceptable_latency_ms
|
33
|
+
]
|
34
|
+
|
35
|
+
attr_reader :replica_set_name,
|
36
|
+
:seeds,
|
37
|
+
:refresh_interval,
|
38
|
+
:refresh_mode,
|
39
|
+
:refresh_version,
|
40
|
+
:manager,
|
41
|
+
:tag_sets,
|
42
|
+
:acceptable_latency
|
29
43
|
|
30
44
|
# Create a connection to a MongoDB replica set.
|
31
45
|
#
|
32
46
|
# If no args are provided, it will check <code>ENV["MONGODB_URI"]</code>.
|
33
47
|
#
|
34
48
|
# Once connected to a replica set, you can find out which nodes are primary, secondary, and
|
35
|
-
# arbiters with the corresponding accessors:
|
36
|
-
#
|
49
|
+
# arbiters with the corresponding accessors: MongoClient#primary, MongoClient#secondaries, and
|
50
|
+
# MongoClient#arbiters. This is useful if your application needs to connect manually to nodes other
|
37
51
|
# than the primary.
|
38
52
|
#
|
39
53
|
# @overload initialize(seeds=ENV["MONGODB_URI"], opts={})
|
40
54
|
# @param [Array<String>, Array<Array(String, Integer)>] seeds
|
41
55
|
#
|
42
|
-
# @option opts [
|
43
|
-
# propagated to DB objects instantiated off of this
|
44
|
-
# default can be overridden upon instantiation of any DB by explicitly setting
|
56
|
+
# @option opts [Hash] :w (1), :j (false), :wtimeout (false), :fsync (false) Set the default write concern
|
57
|
+
# propagated to DB objects instantiated off of this MongoReplicaSetClient. This
|
58
|
+
# default can be overridden upon instantiation of any DB by explicitly setting write concern values
|
45
59
|
# on initialization.
|
46
60
|
# @option opts [:primary, :primary_preferred, :secondary, :secondary_preferred, :nearest] :read_preference (:primary)
|
47
61
|
# A "read preference" determines the candidate replica set members to which a query or command can be sent.
|
@@ -75,18 +89,18 @@ module Mongo
|
|
75
89
|
# will always trigger a complete refresh. This option is useful when you want to add new nodes
|
76
90
|
# or remove replica set nodes not currently in use by the driver.
|
77
91
|
# @option opts [Integer] :refresh_interval (90) If :refresh_mode is enabled, this is the number of seconds
|
78
|
-
# between calls to check the replica set's state.
|
92
|
+
# between calls to check the replica set's state.
|
79
93
|
# @note the number of seed nodes does not have to be equal to the number of replica set members.
|
80
94
|
# The purpose of seed nodes is to permit the driver to find at least one replica set member even if a member is down.
|
81
95
|
#
|
82
96
|
# @example Connect to a replica set and provide two seed nodes.
|
83
|
-
#
|
97
|
+
# MongoReplicaSetClient.new(['localhost:30000', 'localhost:30001'])
|
84
98
|
#
|
85
99
|
# @example Connect to a replica set providing two seed nodes and ensuring a connection to the replica set named 'prod':
|
86
|
-
#
|
100
|
+
# MongoReplicaSetClient.new(['localhost:30000', 'localhost:30001'], :name => 'prod')
|
87
101
|
#
|
88
102
|
# @example Connect to a replica set providing two seed nodes and allowing reads from a secondary node:
|
89
|
-
#
|
103
|
+
# MongoReplicaSetClient.new(['localhost:30000', 'localhost:30001'], :read => :secondary)
|
90
104
|
#
|
91
105
|
# @see http://api.mongodb.org/ruby/current/file.REPLICA_SETS.html Replica sets in Ruby
|
92
106
|
#
|
@@ -96,23 +110,24 @@ module Mongo
|
|
96
110
|
def initialize(*args)
|
97
111
|
opts = args.last.is_a?(Hash) ? args.pop : {}
|
98
112
|
nodes = args
|
113
|
+
nodes = nodes.flatten(1) if nodes.first.is_a?(Array) && nodes.first.first.is_a?(Array)
|
99
114
|
|
100
115
|
if nodes.empty? and ENV.has_key?('MONGODB_URI')
|
101
116
|
parser = URIParser.new ENV['MONGODB_URI']
|
102
117
|
if parser.direct?
|
103
|
-
raise MongoArgumentError, "Mongo::
|
118
|
+
raise MongoArgumentError, "Mongo::MongoReplicaSetClient.new called with no arguments, but ENV['MONGODB_URI'] implies a direct connection."
|
104
119
|
end
|
105
120
|
opts = parser.connection_options.merge! opts
|
106
121
|
nodes = [parser.nodes]
|
107
122
|
end
|
108
123
|
|
109
124
|
unless nodes.length > 0
|
110
|
-
raise MongoArgumentError, "A
|
125
|
+
raise MongoArgumentError, "A MongoReplicaSetClient requires at least one seed node."
|
111
126
|
end
|
112
127
|
|
113
128
|
# This is temporary until support for the old format is dropped
|
114
129
|
if nodes.first.last.is_a?(Integer)
|
115
|
-
warn "Initiating a
|
130
|
+
warn "Initiating a MongoReplicaSetClient with seeds passed as individual [host, port] array arguments is deprecated."
|
116
131
|
warn "Please specify hosts as an array of 'host:port' strings; the old format will be removed in v2.0"
|
117
132
|
@seeds = nodes
|
118
133
|
else
|
@@ -149,11 +164,11 @@ module Mongo
|
|
149
164
|
end
|
150
165
|
|
151
166
|
def valid_opts
|
152
|
-
|
167
|
+
super + REPL_SET_OPTS - CLIENT_ONLY_OPTS
|
153
168
|
end
|
154
169
|
|
155
170
|
def inspect
|
156
|
-
"<Mongo::
|
171
|
+
"<Mongo::MongoReplicaSetClient:0x#{self.object_id.to_s(16)} @seeds=#{@seeds.inspect} " +
|
157
172
|
"@connected=#{@connected}>"
|
158
173
|
end
|
159
174
|
|
@@ -184,7 +199,7 @@ module Mongo
|
|
184
199
|
# Determine whether a replica set refresh is
|
185
200
|
# required. If so, run a hard refresh. You can
|
186
201
|
# force a hard refresh by running
|
187
|
-
#
|
202
|
+
# MongoReplicaSetClient#hard_refresh!
|
188
203
|
#
|
189
204
|
# @return [Boolean] +true+ unless a hard refresh
|
190
205
|
# is run and the refresh lock can't be acquired.
|
@@ -233,7 +248,7 @@ module Mongo
|
|
233
248
|
|
234
249
|
# @deprecated
|
235
250
|
def connecting?
|
236
|
-
warn "
|
251
|
+
warn "MongoReplicaSetClient#connecting? is deprecated and will be removed in v2.0."
|
237
252
|
false
|
238
253
|
end
|
239
254
|
|
@@ -252,8 +267,8 @@ module Mongo
|
|
252
267
|
end
|
253
268
|
|
254
269
|
def nodes
|
255
|
-
warn "
|
256
|
-
"Please use
|
270
|
+
warn "MongoReplicaSetClient#nodes is DEPRECATED and will be removed in v2.0. " +
|
271
|
+
"Please use MongoReplicaSetClient#seeds instead."
|
257
272
|
@seeds
|
258
273
|
end
|
259
274
|
|
@@ -291,8 +306,8 @@ module Mongo
|
|
291
306
|
# @deprecated
|
292
307
|
def reset_connection
|
293
308
|
close
|
294
|
-
warn "
|
295
|
-
"Use
|
309
|
+
warn "MongoReplicaSetClient#reset_connection is now deprecated and will be removed in v2.0. " +
|
310
|
+
"Use MongoReplicaSetClient#close instead."
|
296
311
|
end
|
297
312
|
|
298
313
|
# Returns +true+ if it's okay to read from a secondary node.
|
@@ -335,7 +350,7 @@ module Mongo
|
|
335
350
|
end
|
336
351
|
socket
|
337
352
|
end
|
338
|
-
|
353
|
+
|
339
354
|
def checkout_reader(mode=@read, tag_sets=@tag_sets, acceptable_latency=@acceptable_latency)
|
340
355
|
checkout do
|
341
356
|
pool = read_pool(mode, tag_sets, acceptable_latency)
|
@@ -436,8 +451,8 @@ module Mongo
|
|
436
451
|
# Parse option hash
|
437
452
|
def setup(opts)
|
438
453
|
# Refresh
|
439
|
-
@refresh_mode = opts.
|
440
|
-
@refresh_interval = opts.
|
454
|
+
@refresh_mode = opts.delete(:refresh_mode) || false
|
455
|
+
@refresh_interval = opts.delete(:refresh_interval) || 90
|
441
456
|
|
442
457
|
if @refresh_mode && @refresh_interval < 60
|
443
458
|
@refresh_interval = 60 unless ENV['TEST_MODE'] = 'TRUE'
|
@@ -455,30 +470,30 @@ module Mongo
|
|
455
470
|
if opts[:read_secondary]
|
456
471
|
warn ":read_secondary options has now been deprecated and will " +
|
457
472
|
"be removed in driver v2.0. Use the :read option instead."
|
458
|
-
@read_secondary = opts.
|
473
|
+
@read_secondary = opts.delete(:read_secondary) || false
|
459
474
|
@read = :secondary_preferred
|
460
475
|
else
|
461
|
-
@read = opts.
|
476
|
+
@read = opts.delete(:read) || :primary
|
462
477
|
Mongo::Support.validate_read_preference(@read)
|
463
478
|
end
|
464
479
|
|
465
|
-
@tag_sets = opts.
|
466
|
-
@acceptable_latency = opts.
|
480
|
+
@tag_sets = opts.delete(:tag_sets) || []
|
481
|
+
@acceptable_latency = opts.delete(:secondary_acceptable_latency_ms) || 15
|
467
482
|
|
468
483
|
# Replica set name
|
469
484
|
if opts[:rs_name]
|
470
485
|
warn ":rs_name option has been deprecated and will be removed in v2.0. " +
|
471
486
|
"Please use :name instead."
|
472
|
-
@replica_set_name = opts
|
487
|
+
@replica_set_name = opts.delete(:rs_name)
|
473
488
|
else
|
474
|
-
@replica_set_name = opts
|
489
|
+
@replica_set_name = opts.delete(:name)
|
475
490
|
end
|
476
491
|
|
477
|
-
opts[:connect_timeout] = opts
|
492
|
+
opts[:connect_timeout] = opts.delete(:connect_timeout) || 30
|
478
493
|
|
479
494
|
super opts
|
480
495
|
end
|
481
|
-
|
496
|
+
|
482
497
|
def prune_managers
|
483
498
|
@old_managers.each do |manager|
|
484
499
|
if manager != @manager
|