mongo 1.7.1 → 1.8.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/{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
@@ -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,7 +19,7 @@
|
|
19
19
|
module Mongo
|
20
20
|
|
21
21
|
# Instantiates and manages connections to a MongoDB sharded cluster for high availability.
|
22
|
-
class
|
22
|
+
class MongoShardedClient < MongoReplicaSetClient
|
23
23
|
|
24
24
|
SHARDED_CLUSTER_OPTS = [:refresh_mode, :refresh_interval]
|
25
25
|
|
@@ -34,9 +34,9 @@ module Mongo
|
|
34
34
|
#
|
35
35
|
# @option opts [String] :name (nil) The name of the sharded cluster to connect to. You
|
36
36
|
# can use this option to verify that you're connecting to the right sharded cluster.
|
37
|
-
# @option opts [
|
38
|
-
# propagated to DB objects instantiated off of this
|
39
|
-
# default can be overridden upon instantiation of any DB by explicitly setting a
|
37
|
+
# @option opts [Hash] ::w (1), :j (false), :wtimeout (false), :fsync (false) Set the default write concern
|
38
|
+
# propagated to DB objects instantiated off of this MongoClient. This
|
39
|
+
# default can be overridden upon instantiation of any DB by explicitly setting a write concern values
|
40
40
|
# on initialization.
|
41
41
|
# @option opts [Logger] :logger (nil) Logger instance to receive driver operation log.
|
42
42
|
# @option opts [Integer] :pool_size (1) The maximum number of socket connections allowed per
|
@@ -58,7 +58,7 @@ module Mongo
|
|
58
58
|
# The purpose of seed nodes is to permit the driver to find at least one sharded cluster member even if a member is down.
|
59
59
|
#
|
60
60
|
# @example Connect to a sharded cluster and provide two seed nodes.
|
61
|
-
#
|
61
|
+
# MongoShardedClient.new(['localhost:30000', 'localhost:30001'])
|
62
62
|
#
|
63
63
|
# @raise [MongoArgumentError] This is raised for usage errors.
|
64
64
|
#
|
@@ -71,14 +71,14 @@ module Mongo
|
|
71
71
|
if nodes.empty? and ENV.has_key?('MONGODB_URI')
|
72
72
|
parser = URIParser.new ENV['MONGODB_URI']
|
73
73
|
if parser.direct?
|
74
|
-
raise MongoArgumentError, "Mongo::
|
74
|
+
raise MongoArgumentError, "Mongo::MongoShardedClient.new called with no arguments, but ENV['MONGODB_URI'] implies a direct connection."
|
75
75
|
end
|
76
76
|
opts = parser.connection_options.merge! opts
|
77
77
|
nodes = [parser.nodes]
|
78
78
|
end
|
79
79
|
|
80
80
|
unless nodes.length > 0
|
81
|
-
raise MongoArgumentError, "A
|
81
|
+
raise MongoArgumentError, "A MongoShardedClient requires at least one seed node."
|
82
82
|
end
|
83
83
|
|
84
84
|
@seeds = nodes.map do |host_port|
|
@@ -118,7 +118,7 @@ module Mongo
|
|
118
118
|
end
|
119
119
|
|
120
120
|
def inspect
|
121
|
-
"<Mongo::
|
121
|
+
"<Mongo::MongoShardedClient:0x#{self.object_id.to_s(16)} @seeds=#{@seeds.inspect} " +
|
122
122
|
"@connected=#{@connected}>"
|
123
123
|
end
|
124
124
|
|
data/lib/mongo/networking.rb
CHANGED
@@ -18,7 +18,7 @@ module Mongo
|
|
18
18
|
# @return [Integer] number of bytes sent
|
19
19
|
def send_message(operation, message, opts={})
|
20
20
|
if opts.is_a?(String)
|
21
|
-
warn "
|
21
|
+
warn "MongoClient#send_message no longer takes a string log message. " +
|
22
22
|
"Logging is now handled within the Collection and Cursor classes."
|
23
23
|
opts = {}
|
24
24
|
end
|
@@ -56,12 +56,11 @@ module Mongo
|
|
56
56
|
# @see DB#get_last_error for valid last error params.
|
57
57
|
#
|
58
58
|
# @return [Hash] The document returned by the call to getlasterror.
|
59
|
-
def
|
59
|
+
def send_message_with_gle(operation, message, db_name, log_message=nil, write_concern=false)
|
60
60
|
docs = num_received = cursor_id = ''
|
61
61
|
add_message_headers(message, operation)
|
62
62
|
|
63
|
-
last_error_message =
|
64
|
-
build_last_error_message(last_error_message, db_name, last_error_params)
|
63
|
+
last_error_message = build_get_last_error_message(db_name, write_concern)
|
65
64
|
last_error_id = add_message_headers(last_error_message, Mongo::Constants::OP_QUERY)
|
66
65
|
|
67
66
|
packed_message = message.append!(last_error_message).to_s
|
@@ -181,7 +180,7 @@ module Mongo
|
|
181
180
|
|
182
181
|
# unpacks to flags, cursor_id_a, cursor_id_b, starting_from, number_remaining
|
183
182
|
flags, cursor_id_a, cursor_id_b, _, number_remaining = header_buf.unpack('VVVVV')
|
184
|
-
|
183
|
+
|
185
184
|
check_response_flags(flags)
|
186
185
|
cursor_id = (cursor_id_b << 32) + cursor_id_a
|
187
186
|
[number_remaining, cursor_id]
|
@@ -209,23 +208,28 @@ module Mongo
|
|
209
208
|
[docs, number_received]
|
210
209
|
end
|
211
210
|
|
212
|
-
|
213
|
-
|
214
|
-
#
|
215
|
-
# Because it modifies message by reference, we don't need to return it.
|
216
|
-
def build_last_error_message(message, db_name, opts)
|
211
|
+
def build_command_message(db_name, query, projection=nil, skip=0, limit=-1)
|
212
|
+
message = BSON::ByteBuffer.new
|
217
213
|
message.put_int(0)
|
218
214
|
BSON::BSON_RUBY.serialize_cstr(message, "#{db_name}.$cmd")
|
219
|
-
message.put_int(
|
220
|
-
message.put_int(
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
215
|
+
message.put_int(skip)
|
216
|
+
message.put_int(limit)
|
217
|
+
message.put_binary(BSON::BSON_CODER.serialize(query, false).to_s)
|
218
|
+
message.put_binary(BSON::BSON_CODER.serialize(projection, false).to_s) if projection
|
219
|
+
message
|
220
|
+
end
|
221
|
+
|
222
|
+
# Constructs a getlasterror message. This method is used exclusively by
|
223
|
+
# MongoClient#send_message_with_gle.
|
224
|
+
def build_get_last_error_message(db_name, write_concern)
|
225
|
+
gle = BSON::OrderedHash.new
|
226
|
+
gle[:getlasterror] = 1
|
227
|
+
if write_concern.is_a?(Hash)
|
228
|
+
write_concern.assert_valid_keys(:w, :wtimeout, :fsync, :j)
|
229
|
+
gle.merge!(write_concern)
|
230
|
+
gle.delete(:w) if gle[:w] == 1
|
226
231
|
end
|
227
|
-
|
228
|
-
nil
|
232
|
+
build_command_message(db_name, gle)
|
229
233
|
end
|
230
234
|
|
231
235
|
# Prepares a message for transmission to MongoDB by
|
@@ -282,6 +286,7 @@ module Mongo
|
|
282
286
|
end
|
283
287
|
total_bytes_sent
|
284
288
|
rescue => ex
|
289
|
+
socket.close
|
285
290
|
raise ConnectionFailure, "Operation failed with the following exception: #{ex}:#{ex.message}"
|
286
291
|
end
|
287
292
|
end
|
@@ -306,7 +311,7 @@ module Mongo
|
|
306
311
|
def receive_data(length, socket)
|
307
312
|
message = new_binary_string
|
308
313
|
socket.read(length, message)
|
309
|
-
|
314
|
+
|
310
315
|
raise ConnectionFailure, "connection closed" unless message && message.length > 0
|
311
316
|
if message.length < length
|
312
317
|
chunk = new_binary_string
|
data/lib/mongo/util/core_ext.rb
CHANGED
data/lib/mongo/util/logging.rb
CHANGED
@@ -29,17 +29,28 @@ module Mongo
|
|
29
29
|
# Execute the block and log the operation described by name and payload.
|
30
30
|
def instrument(name, payload = {})
|
31
31
|
start_time = Time.now
|
32
|
-
res =
|
33
|
-
|
32
|
+
res = Logging.instrumenter.instrument(name, payload) do
|
33
|
+
yield
|
34
|
+
end
|
35
|
+
duration = Time.now - start_time
|
36
|
+
log_operation(name, payload, duration)
|
34
37
|
res
|
35
38
|
end
|
36
39
|
|
40
|
+
def self.instrumenter
|
41
|
+
@instrumenter || Instrumenter
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.instrumenter=(instrumenter)
|
45
|
+
@instrumenter = instrumenter
|
46
|
+
end
|
47
|
+
|
37
48
|
protected
|
38
49
|
|
39
|
-
def log_operation(name, payload,
|
50
|
+
def log_operation(name, payload, duration)
|
40
51
|
@logger && @logger.debug do
|
41
52
|
msg = "MONGODB "
|
42
|
-
msg << "(
|
53
|
+
msg << "(%.1fms) " % (duration * 1000)
|
43
54
|
msg << "#{payload[:database]}['#{payload[:collection]}'].#{name}("
|
44
55
|
msg << payload.values_at(:selector, :document, :documents, :fields ).compact.map(&:inspect).join(', ') + ")"
|
45
56
|
msg << ".skip(#{payload[:skip]})" if payload[:skip]
|
@@ -49,5 +60,10 @@ module Mongo
|
|
49
60
|
end
|
50
61
|
end
|
51
62
|
|
63
|
+
module Instrumenter
|
64
|
+
def self.instrument(name, payload = {})
|
65
|
+
yield
|
66
|
+
end
|
67
|
+
end
|
52
68
|
end
|
53
69
|
end
|
data/lib/mongo/util/node.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
module Mongo
|
2
2
|
class Node
|
3
3
|
|
4
|
-
attr_accessor :host, :port, :address, :config, :
|
4
|
+
attr_accessor :host, :port, :address, :config, :client, :socket, :last_state
|
5
5
|
|
6
|
-
def initialize(
|
7
|
-
@
|
6
|
+
def initialize(client, host_port)
|
7
|
+
@client = client
|
8
8
|
@host, @port = split_node(host_port)
|
9
9
|
@address = "#{@host}:#{@port}"
|
10
10
|
@config = nil
|
@@ -29,11 +29,11 @@ module Mongo
|
|
29
29
|
# return nil.
|
30
30
|
def connect
|
31
31
|
begin
|
32
|
-
socket = @
|
33
|
-
@
|
32
|
+
socket = @client.socket_class.new(@host, @port,
|
33
|
+
@client.op_timeout, @client.connect_timeout
|
34
34
|
)
|
35
35
|
rescue OperationTimeout, ConnectionFailure, OperationFailure, SocketError, SystemCallError, IOError => ex
|
36
|
-
@
|
36
|
+
@client.log(:debug, "Failed connection to #{host_string} with #{ex.class}, #{ex.message}.")
|
37
37
|
socket.close if socket
|
38
38
|
end
|
39
39
|
|
@@ -54,7 +54,7 @@ module Mongo
|
|
54
54
|
|
55
55
|
def active?
|
56
56
|
begin
|
57
|
-
result = @
|
57
|
+
result = @client['admin'].command({:ping => 1}, :socket => @socket)
|
58
58
|
rescue OperationFailure, SocketError, SystemCallError, IOError
|
59
59
|
return nil
|
60
60
|
end
|
@@ -66,16 +66,16 @@ module Mongo
|
|
66
66
|
# matches with the name provided.
|
67
67
|
def set_config
|
68
68
|
begin
|
69
|
-
@config = @
|
69
|
+
@config = @client['admin'].command({:ismaster => 1}, :socket => @socket)
|
70
70
|
|
71
71
|
if @config['msg']
|
72
|
-
@
|
72
|
+
@client.log(:warn, "#{config['msg']}")
|
73
73
|
end
|
74
74
|
|
75
75
|
check_set_membership(config)
|
76
76
|
check_set_name(config)
|
77
77
|
rescue ConnectionFailure, OperationFailure, OperationTimeout, SocketError, SystemCallError, IOError => ex
|
78
|
-
@
|
78
|
+
@client.log(:warn, "Attempted connection to node #{host_string} raised " +
|
79
79
|
"#{ex.class}: #{ex.message}")
|
80
80
|
|
81
81
|
# Socket may already be nil from issuing command
|
@@ -145,12 +145,12 @@ module Mongo
|
|
145
145
|
end
|
146
146
|
|
147
147
|
host = host_port[0]
|
148
|
-
port = host_port[1].nil? ?
|
148
|
+
port = host_port[1].nil? ? MongoClient::DEFAULT_PORT : host_port[1].to_i
|
149
149
|
|
150
150
|
[host, port]
|
151
151
|
end
|
152
152
|
|
153
|
-
# Ensure that this node is a
|
153
|
+
# Ensure that this node is a healthy member of a replica set.
|
154
154
|
def check_set_membership(config)
|
155
155
|
if !config.has_key?('hosts')
|
156
156
|
message = "Will not connect to #{host_string} because it's not a member " +
|
@@ -165,13 +165,13 @@ module Mongo
|
|
165
165
|
|
166
166
|
# Ensure that this node is part of a replica set of the expected name.
|
167
167
|
def check_set_name(config)
|
168
|
-
if @
|
168
|
+
if @client.replica_set_name
|
169
169
|
if !config['setName']
|
170
|
-
@
|
170
|
+
@client.log(:warn, "Could not verify replica set name for member #{host_string} " +
|
171
171
|
"because ismaster does not return name in this version of MongoDB")
|
172
|
-
elsif @
|
172
|
+
elsif @client.replica_set_name != config['setName']
|
173
173
|
message = "Attempting to connect to replica set '#{config['setName']}' on member #{host_string} " +
|
174
|
-
"but expected '#{@
|
174
|
+
"but expected '#{@client.replica_set_name}'"
|
175
175
|
raise ReplicaSetConnectionError, message
|
176
176
|
end
|
177
177
|
end
|
data/lib/mongo/util/pool.rb
CHANGED
@@ -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.
|
@@ -21,12 +21,17 @@ module Mongo
|
|
21
21
|
MAX_PING_TIME = 1_000_000
|
22
22
|
PRUNE_INTERVAL = 10_000
|
23
23
|
|
24
|
-
attr_accessor :host,
|
25
|
-
|
24
|
+
attr_accessor :host,
|
25
|
+
:port,
|
26
|
+
:address,
|
27
|
+
:size,
|
28
|
+
:timeout,
|
29
|
+
:checked_out,
|
30
|
+
:client
|
26
31
|
|
27
32
|
# Create a new pool of connections.
|
28
|
-
def initialize(
|
29
|
-
@
|
33
|
+
def initialize(client, host, port, opts={})
|
34
|
+
@client = client
|
30
35
|
|
31
36
|
@host, @port = host, port
|
32
37
|
|
@@ -43,25 +48,28 @@ module Mongo
|
|
43
48
|
# Mutex for synchronizing pool access
|
44
49
|
@connection_mutex = Mutex.new
|
45
50
|
|
51
|
+
# Mutex for synchronizing pings
|
52
|
+
@ping_mutex = Mutex.new
|
53
|
+
|
46
54
|
# Condition variable for signal and wait
|
47
55
|
@queue = ConditionVariable.new
|
48
56
|
|
49
57
|
# Operations to perform on a socket
|
50
58
|
@socket_ops = Hash.new { |h, k| h[k] = [] }
|
51
59
|
|
52
|
-
@sockets
|
53
|
-
@pids
|
54
|
-
@checked_out
|
55
|
-
@ping_time
|
56
|
-
@last_ping
|
57
|
-
@closed
|
60
|
+
@sockets = []
|
61
|
+
@pids = {}
|
62
|
+
@checked_out = []
|
63
|
+
@ping_time = nil
|
64
|
+
@last_ping = nil
|
65
|
+
@closed = false
|
58
66
|
@threads_to_sockets = {}
|
59
67
|
@checkout_counter = 0
|
60
68
|
end
|
61
69
|
|
62
70
|
# Close this pool.
|
63
71
|
#
|
64
|
-
# @option opts [Boolean]
|
72
|
+
# @option opts [Boolean]:soft (false) If true,
|
65
73
|
# close only those sockets that are not checked out.
|
66
74
|
def close(opts={})
|
67
75
|
@connection_mutex.synchronize do
|
@@ -85,6 +93,29 @@ module Mongo
|
|
85
93
|
@closed
|
86
94
|
end
|
87
95
|
|
96
|
+
def up?
|
97
|
+
!@closed
|
98
|
+
end
|
99
|
+
|
100
|
+
def matches_mode(mode)
|
101
|
+
if mode == :primary && @node.secondary? ||
|
102
|
+
mode == :secondary && @node.primary?
|
103
|
+
false
|
104
|
+
else
|
105
|
+
true
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def matches_tag_set(tag_set)
|
110
|
+
tag_set.all? do |tag, value|
|
111
|
+
tags.has_key?(tag) && tags[tag] == value
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def matches_tag_sets(tag_sets)
|
116
|
+
tag_sets.all? {|set| matches_tag_set(set)}
|
117
|
+
end
|
118
|
+
|
88
119
|
def inspect
|
89
120
|
"#<Mongo::Pool:0x#{self.object_id.to_s(16)} @host=#{@host} @port=#{port} " +
|
90
121
|
"@ping_time=#{@ping_time} #{@checked_out.size}/#{@size} sockets available " +
|
@@ -102,15 +133,13 @@ module Mongo
|
|
102
133
|
# Refresh ping time only if we haven't
|
103
134
|
# checked within the last five minutes.
|
104
135
|
def ping_time
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
@ping_time = refresh_ping_time
|
111
|
-
else
|
112
|
-
@ping_time
|
136
|
+
@ping_mutex.synchronize do
|
137
|
+
if !@last_ping || (Time.now - @last_ping) > 300
|
138
|
+
@ping_time = refresh_ping_time
|
139
|
+
@last_ping = Time.now
|
140
|
+
end
|
113
141
|
end
|
142
|
+
@ping_time
|
114
143
|
end
|
115
144
|
|
116
145
|
# Return the time it takes on average
|
@@ -139,7 +168,7 @@ module Mongo
|
|
139
168
|
|
140
169
|
def ping
|
141
170
|
begin
|
142
|
-
return self.
|
171
|
+
return self.client['admin'].command({:ping => 1}, :socket => @node.socket, :timeout => MAX_PING_TIME)
|
143
172
|
rescue ConnectionFailure, OperationFailure, SocketError, SystemCallError, IOError
|
144
173
|
return false
|
145
174
|
end
|
@@ -163,7 +192,7 @@ module Mongo
|
|
163
192
|
# therefore, it runs within a mutex.
|
164
193
|
def checkout_new_socket
|
165
194
|
begin
|
166
|
-
socket = @
|
195
|
+
socket = @client.socket_class.new(@host, @port, @client.op_timeout)
|
167
196
|
socket.pool = self
|
168
197
|
rescue => ex
|
169
198
|
socket.close if socket
|
@@ -173,7 +202,7 @@ module Mongo
|
|
173
202
|
|
174
203
|
# If any saved authentications exist, we want to apply those
|
175
204
|
# when creating new sockets.
|
176
|
-
@
|
205
|
+
@client.apply_saved_authentication(:socket => socket)
|
177
206
|
|
178
207
|
@sockets << socket
|
179
208
|
@pids[socket] = Process.pid
|
@@ -190,7 +219,7 @@ module Mongo
|
|
190
219
|
@connection_mutex.synchronize do
|
191
220
|
@sockets.each do |socket|
|
192
221
|
@socket_ops[socket] << Proc.new do
|
193
|
-
@
|
222
|
+
@client.apply_saved_authentication(:socket => socket)
|
194
223
|
end
|
195
224
|
end
|
196
225
|
end
|
@@ -202,7 +231,7 @@ module Mongo
|
|
202
231
|
@connection_mutex.synchronize do
|
203
232
|
@sockets.each do |socket|
|
204
233
|
@socket_ops[socket] << Proc.new do
|
205
|
-
@
|
234
|
+
@client.db(db).issue_logout(:socket => socket)
|
206
235
|
end
|
207
236
|
end
|
208
237
|
end
|
@@ -246,7 +275,7 @@ module Mongo
|
|
246
275
|
# pool size has not been exceeded. Otherwise, wait for the next
|
247
276
|
# available socket.
|
248
277
|
def checkout
|
249
|
-
@
|
278
|
+
@client.connect if !@client.connected?
|
250
279
|
start_time = Time.now
|
251
280
|
loop do
|
252
281
|
if (Time.now - start_time) > @timeout
|
@@ -297,7 +326,7 @@ module Mongo
|
|
297
326
|
|
298
327
|
socket = checkout_new_socket
|
299
328
|
end
|
300
|
-
|
329
|
+
|
301
330
|
return socket
|
302
331
|
else
|
303
332
|
# Otherwise, wait
|