mongo 1.8.2 → 1.8.3.rc0
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +0 -0
- data/LICENSE +1 -1
- data/README.md +2 -7
- data/VERSION +1 -1
- data/lib/mongo.rb +2 -18
- data/lib/mongo/collection.rb +20 -24
- data/lib/mongo/cursor.rb +30 -35
- data/lib/mongo/db.rb +1 -19
- data/lib/mongo/exceptions.rb +0 -19
- data/lib/mongo/gridfs/grid.rb +18 -29
- data/lib/mongo/gridfs/grid_ext.rb +0 -18
- data/lib/mongo/gridfs/grid_file_system.rb +17 -26
- data/lib/mongo/gridfs/grid_io.rb +0 -18
- data/lib/mongo/legacy.rb +0 -18
- data/lib/mongo/mongo_client.rb +11 -33
- data/lib/mongo/mongo_replica_set_client.rb +29 -56
- data/lib/mongo/mongo_sharded_client.rb +38 -50
- data/lib/mongo/networking.rb +5 -4
- data/lib/mongo/util/conversions.rb +0 -17
- data/lib/mongo/util/core_ext.rb +0 -18
- data/lib/mongo/util/node.rb +16 -3
- data/lib/mongo/util/pool.rb +46 -36
- data/lib/mongo/util/pool_manager.rb +102 -71
- data/lib/mongo/util/read_preference.rb +4 -2
- data/lib/mongo/util/server_version.rb +0 -17
- data/lib/mongo/util/sharding_pool_manager.rb +4 -23
- data/lib/mongo/util/socket_util.rb +20 -0
- data/lib/mongo/util/ssl_socket.rb +10 -19
- data/lib/mongo/util/support.rb +0 -18
- data/lib/mongo/util/tcp_socket.rb +1 -9
- data/lib/mongo/util/thread_local_variable_manager.rb +0 -18
- data/lib/mongo/util/uri_parser.rb +87 -82
- data/lib/mongo/util/write_concern.rb +0 -18
- data/mongo.gemspec +4 -1
- data/test/auxillary/pool_reuse_test.rb +65 -0
- data/test/functional/collection_test.rb +92 -3
- data/test/functional/connection_test.rb +30 -6
- data/test/functional/db_api_test.rb +11 -0
- data/test/functional/timeout_test.rb +23 -0
- data/test/functional/uri_test.rb +69 -0
- data/test/replica_set/client_test.rb +0 -22
- data/test/replica_set/cursor_test.rb +11 -5
- data/test/replica_set/refresh_test.rb +0 -0
- data/test/replica_set/z_cluster_shutdown.rb +13 -0
- data/test/sharded_cluster/basic_test.rb +46 -32
- data/test/test_helper.rb +26 -1
- data/test/threading/basic_test.rb +10 -9
- data/test/tools/mongo_config.rb +6 -2
- data/test/unit/collection_test.rb +1 -1
- data/test/unit/grid_test.rb +20 -13
- data/test/unit/mongo_sharded_client_test.rb +32 -0
- data/test/unit/pool_manager_test.rb +28 -14
- metadata +45 -12
- metadata.gz.sig +0 -0
@@ -34,8 +34,10 @@ module Mongo
|
|
34
34
|
end
|
35
35
|
|
36
36
|
def select_pool(mode, tags, latency)
|
37
|
+
return primary_pool if @client.mongos?
|
38
|
+
|
37
39
|
if mode == :primary && !tags.empty?
|
38
|
-
raise MongoArgumentError, "Read
|
40
|
+
raise MongoArgumentError, "Read preference :primary cannot be combined with tags"
|
39
41
|
end
|
40
42
|
|
41
43
|
case mode
|
@@ -79,4 +81,4 @@ module Mongo
|
|
79
81
|
near_pools[ rand(near_pools.length) ]
|
80
82
|
end
|
81
83
|
end
|
82
|
-
end
|
84
|
+
end
|
@@ -1,20 +1,3 @@
|
|
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
1
|
module Mongo
|
19
2
|
# Simple class for comparing server versions.
|
20
3
|
class ServerVersion
|
@@ -1,21 +1,6 @@
|
|
1
1
|
|
2
2
|
module Mongo
|
3
3
|
class ShardingPoolManager < PoolManager
|
4
|
-
|
5
|
-
attr_reader :client, :primary, :primary_pool, :hosts, :nodes,
|
6
|
-
:max_bson_size, :members
|
7
|
-
|
8
|
-
# Create a new set of connection pools.
|
9
|
-
#
|
10
|
-
# The pool manager will by default use the original seed list passed
|
11
|
-
# to the connection objects, accessible via connection.seeds. In addition,
|
12
|
-
# the user may pass an additional list of seeds nodes discovered in real
|
13
|
-
# time. The union of these lists will be used when attempting to connect,
|
14
|
-
# with the newly-discovered nodes being used first.
|
15
|
-
def initialize(client, seeds=[])
|
16
|
-
super
|
17
|
-
end
|
18
|
-
|
19
4
|
def inspect
|
20
5
|
"<Mongo::ShardingPoolManager:0x#{self.object_id.to_s(16)} @seeds=#{@seeds}>"
|
21
6
|
end
|
@@ -27,14 +12,10 @@ module Mongo
|
|
27
12
|
end
|
28
13
|
|
29
14
|
def connect
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
members
|
34
|
-
initialize_pools(best(members))
|
35
|
-
|
36
|
-
@members = members
|
37
|
-
@previously_connected = true
|
15
|
+
@refresh_required = false
|
16
|
+
disconnect_old_members
|
17
|
+
connect_to_members
|
18
|
+
initialize_pools best(@members)
|
38
19
|
end
|
39
20
|
|
40
21
|
# We want to refresh to the member with the fastest ping time
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module SocketUtil
|
2
|
+
|
3
|
+
attr_accessor :pool, :pid
|
4
|
+
|
5
|
+
def checkout
|
6
|
+
@pool.checkout if @pool
|
7
|
+
end
|
8
|
+
|
9
|
+
def checkin
|
10
|
+
@pool.checkin(self) if @pool
|
11
|
+
end
|
12
|
+
|
13
|
+
def close
|
14
|
+
@socket.close unless closed?
|
15
|
+
end
|
16
|
+
|
17
|
+
def closed?
|
18
|
+
@socket.closed?
|
19
|
+
end
|
20
|
+
end
|
@@ -8,19 +8,18 @@ module Mongo
|
|
8
8
|
# a TCP connection over SSL and then provides an basic interface
|
9
9
|
# mirroring Ruby's TCPSocket, vis., TCPSocket#send and TCPSocket#read.
|
10
10
|
class SSLSocket
|
11
|
-
|
12
|
-
attr_accessor :pool, :pid
|
11
|
+
include SocketUtil
|
13
12
|
|
14
13
|
def initialize(host, port, op_timeout=nil, connect_timeout=nil)
|
15
14
|
@op_timeout = op_timeout
|
16
15
|
@connect_timeout = connect_timeout
|
17
16
|
@pid = Process.pid
|
18
17
|
|
19
|
-
@
|
20
|
-
@
|
18
|
+
@tcp_socket = ::TCPSocket.new(host, port)
|
19
|
+
@tcp_socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
|
21
20
|
|
22
|
-
@
|
23
|
-
@
|
21
|
+
@socket = OpenSSL::SSL::SSLSocket.new(@tcp_socket)
|
22
|
+
@socket.sync_close = true
|
24
23
|
|
25
24
|
connect
|
26
25
|
end
|
@@ -28,33 +27,25 @@ module Mongo
|
|
28
27
|
def connect
|
29
28
|
if @connect_timeout
|
30
29
|
Timeout::timeout(@connect_timeout, ConnectionTimeoutError) do
|
31
|
-
@
|
30
|
+
@socket.connect
|
32
31
|
end
|
33
32
|
else
|
34
|
-
@
|
33
|
+
@socket.connect
|
35
34
|
end
|
36
35
|
end
|
37
36
|
|
38
37
|
def send(data)
|
39
|
-
@
|
38
|
+
@socket.syswrite(data)
|
40
39
|
end
|
41
40
|
|
42
41
|
def read(length, buffer)
|
43
42
|
if @op_timeout
|
44
43
|
Timeout::timeout(@op_timeout, OperationTimeout) do
|
45
|
-
@
|
44
|
+
@socket.sysread(length, buffer)
|
46
45
|
end
|
47
46
|
else
|
48
|
-
@
|
47
|
+
@socket.sysread(length, buffer)
|
49
48
|
end
|
50
49
|
end
|
51
|
-
|
52
|
-
def close
|
53
|
-
@ssl.close
|
54
|
-
end
|
55
|
-
|
56
|
-
def closed?
|
57
|
-
@ssl.closed?
|
58
|
-
end
|
59
50
|
end
|
60
51
|
end
|
data/lib/mongo/util/support.rb
CHANGED
@@ -1,21 +1,3 @@
|
|
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
1
|
require 'digest/md5'
|
20
2
|
|
21
3
|
module Mongo
|
@@ -8,7 +8,7 @@ module Mongo
|
|
8
8
|
# sans Timeout::timeout
|
9
9
|
#
|
10
10
|
class TCPSocket
|
11
|
-
|
11
|
+
include SocketUtil
|
12
12
|
|
13
13
|
def initialize(host, port, op_timeout=nil, connect_timeout=nil)
|
14
14
|
@op_timeout = op_timeout
|
@@ -58,13 +58,5 @@ module Mongo
|
|
58
58
|
raise ConnectionFailure, ex
|
59
59
|
end
|
60
60
|
end
|
61
|
-
|
62
|
-
def close
|
63
|
-
@socket.close
|
64
|
-
end
|
65
|
-
|
66
|
-
def closed?
|
67
|
-
@socket.closed?
|
68
|
-
end
|
69
61
|
end
|
70
62
|
end
|
@@ -1,21 +1,3 @@
|
|
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
1
|
#:nodoc:
|
20
2
|
module Mongo
|
21
3
|
module ThreadLocalVariableManager
|
@@ -1,21 +1,3 @@
|
|
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
1
|
require 'cgi'
|
20
2
|
|
21
3
|
module Mongo
|
@@ -36,83 +18,100 @@ module Mongo
|
|
36
18
|
|
37
19
|
SPEC_ATTRS = [:nodes, :auths]
|
38
20
|
|
21
|
+
READ_PREFERENCES = {
|
22
|
+
"primary" => :primary,
|
23
|
+
"primarypreferred" => :primary_preferred,
|
24
|
+
"secondary" => :secondary,
|
25
|
+
"secondarypreferred" => :secondary_preferred,
|
26
|
+
"nearest" => :nearest
|
27
|
+
}
|
28
|
+
|
39
29
|
OPT_ATTRS = [
|
40
30
|
:connect,
|
31
|
+
:connecttimeoutms,
|
32
|
+
:fsync,
|
33
|
+
:journal,
|
34
|
+
:pool_size,
|
35
|
+
:readpreference,
|
41
36
|
:replicaset,
|
37
|
+
:safe,
|
42
38
|
:slaveok,
|
39
|
+
:sockettimeoutms,
|
43
40
|
:ssl,
|
44
|
-
:safe,
|
45
41
|
:w,
|
46
42
|
:wtimeout,
|
47
|
-
:
|
48
|
-
:journal,
|
49
|
-
:connecttimeoutms,
|
50
|
-
:sockettimeoutms,
|
51
|
-
:wtimeoutms,
|
52
|
-
:pool_size
|
43
|
+
:wtimeoutms
|
53
44
|
]
|
54
45
|
|
55
|
-
OPT_VALID
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
46
|
+
OPT_VALID = {
|
47
|
+
:connect => lambda { |arg| [ 'direct', 'replicaset', 'true', 'false', true, false ].include?(arg) },
|
48
|
+
:connecttimeoutms => lambda { |arg| arg =~ /^\d+$/ },
|
49
|
+
:fsync => lambda { |arg| ['true', 'false'].include?(arg) },
|
50
|
+
:journal => lambda { |arg| ['true', 'false'].include?(arg) },
|
51
|
+
:pool_size => lambda { |arg| arg.to_i > 0 },
|
52
|
+
:readpreference => lambda { |arg| READ_PREFERENCES.keys.include?(arg) },
|
53
|
+
:replicaset => lambda { |arg| arg.length > 0 },
|
54
|
+
:safe => lambda { |arg| ['true', 'false'].include?(arg) },
|
55
|
+
:slaveok => lambda { |arg| ['true', 'false'].include?(arg) },
|
56
|
+
:sockettimeoutms => lambda { |arg| arg =~ /^\d+$/ },
|
57
|
+
:ssl => lambda { |arg| ['true', 'false'].include?(arg) },
|
58
|
+
:w => lambda { |arg| arg =~ /^\w+$/ },
|
59
|
+
:wtimeout => lambda { |arg| arg =~ /^\d+$/ },
|
60
|
+
:wtimeoutms => lambda { |arg| arg =~ /^\d+$/ }
|
61
|
+
}
|
62
|
+
|
63
|
+
OPT_ERR = {
|
64
|
+
:connect => "must be 'direct', 'replicaset', 'true', or 'false'",
|
65
|
+
:connecttimeoutms => "must be an integer specifying milliseconds",
|
66
|
+
:fsync => "must be 'true' or 'false'",
|
67
|
+
:journal => "must be 'true' or 'false'",
|
68
|
+
:pool_size => "must be an integer greater than zero",
|
69
|
+
:readpreference => "must be on of #{READ_PREFERENCES.keys.map(&:inspect).join(",")}",
|
70
|
+
:replicaset => "must be a string containing the name of the replica set to connect to",
|
71
|
+
:safe => "must be 'true' or 'false'",
|
72
|
+
:slaveok => "must be 'true' or 'false'",
|
73
|
+
:sockettimeoutms => "must be an integer specifying milliseconds",
|
74
|
+
:ssl => "must be 'true' or 'false'",
|
75
|
+
:w => "must be an integer indicating number of nodes to replicate to or a string " +
|
76
|
+
"specifying that replication is required to the majority or nodes with a " +
|
77
|
+
"particilar getLastErrorMode.",
|
78
|
+
:wtimeout => "must be an integer specifying milliseconds",
|
79
|
+
:wtimeoutms => "must be an integer specifying milliseconds"
|
80
|
+
}
|
81
|
+
|
82
|
+
OPT_CONV = {
|
83
|
+
:connect => lambda { |arg| arg == 'false' ? false : arg }, # convert 'false' to FalseClass
|
84
|
+
:connecttimeoutms => lambda { |arg| arg.to_f / 1000 }, # stored as seconds
|
85
|
+
:fsync => lambda { |arg| arg == 'true' ? true : false },
|
86
|
+
:journal => lambda { |arg| arg == 'true' ? true : false },
|
87
|
+
:pool_size => lambda { |arg| arg.to_i },
|
88
|
+
:readpreference => lambda { |arg| READ_PREFERENCES[arg] },
|
89
|
+
:replicaset => lambda { |arg| arg },
|
90
|
+
:safe => lambda { |arg| arg == 'true' ? true : false },
|
91
|
+
:slaveok => lambda { |arg| arg == 'true' ? true : false },
|
92
|
+
:sockettimeoutms => lambda { |arg| arg.to_f / 1000 }, # stored as seconds
|
93
|
+
:ssl => lambda { |arg| arg == 'true' ? true : false },
|
94
|
+
:w => lambda { |arg| Mongo::Support.is_i?(arg) ? arg.to_i : arg.to_sym },
|
95
|
+
:wtimeout => lambda { |arg| arg.to_i },
|
96
|
+
:wtimeoutms => lambda { |arg| arg.to_i }
|
97
|
+
}
|
100
98
|
|
101
99
|
attr_reader :auths,
|
102
100
|
:connect,
|
101
|
+
:connecttimeoutms,
|
102
|
+
:fsync,
|
103
|
+
:journal,
|
104
|
+
:nodes,
|
105
|
+
:pool_size,
|
106
|
+
:readpreference,
|
103
107
|
:replicaset,
|
108
|
+
:safe,
|
104
109
|
:slaveok,
|
110
|
+
:sockettimeoutms,
|
105
111
|
:ssl,
|
106
|
-
:safe,
|
107
112
|
:w,
|
108
113
|
:wtimeout,
|
109
|
-
:
|
110
|
-
:journal,
|
111
|
-
:connecttimeoutms,
|
112
|
-
:sockettimeoutms,
|
113
|
-
:wtimeoutms,
|
114
|
-
:pool_size,
|
115
|
-
:nodes
|
114
|
+
:wtimeoutms
|
116
115
|
|
117
116
|
# Parse a MongoDB URI. This method is used by MongoClient.from_uri.
|
118
117
|
# Returns an array of nodes and an array of db authorizations, if applicable.
|
@@ -141,8 +140,8 @@ module Mongo
|
|
141
140
|
# @note Don't confuse this with attribute getter method #connect.
|
142
141
|
#
|
143
142
|
# @return [MongoClient,MongoReplicaSetClient]
|
144
|
-
def connection(extra_opts, legacy=false)
|
145
|
-
opts = connection_options.merge!
|
143
|
+
def connection(extra_opts, legacy = false, sharded = false)
|
144
|
+
opts = connection_options.merge!(extra_opts)
|
146
145
|
if(legacy)
|
147
146
|
if replicaset?
|
148
147
|
ReplSetConnection.new(node_strings, opts)
|
@@ -150,7 +149,9 @@ module Mongo
|
|
150
149
|
Connection.new(host, port, opts)
|
151
150
|
end
|
152
151
|
else
|
153
|
-
if
|
152
|
+
if sharded
|
153
|
+
MongoShardedClient.new(node_strings, opts)
|
154
|
+
elsif replicaset?
|
154
155
|
MongoReplicaSetClient.new(node_strings, opts)
|
155
156
|
else
|
156
157
|
MongoClient.new(host, port, opts)
|
@@ -219,7 +220,11 @@ module Mongo
|
|
219
220
|
opts[:pool_size] = @pool_size
|
220
221
|
end
|
221
222
|
|
222
|
-
if @
|
223
|
+
if @readpreference && replicaset?
|
224
|
+
opts[:read] = @readpreference
|
225
|
+
end
|
226
|
+
|
227
|
+
if @slaveok && !@readpreference
|
223
228
|
if direct?
|
224
229
|
opts[:slave_ok] = true
|
225
230
|
else
|