mongo 2.14.0 → 2.14.1
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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/lib/mongo/background_thread.rb +11 -0
- data/lib/mongo/cluster/sdam_flow.rb +14 -0
- data/lib/mongo/cluster.rb +0 -26
- data/lib/mongo/collection/view/iterable.rb +16 -6
- data/lib/mongo/collection.rb +2 -0
- data/lib/mongo/cursor.rb +10 -0
- data/lib/mongo/database.rb +14 -2
- data/lib/mongo/grid/fs_bucket.rb +37 -37
- data/lib/mongo/operation/parallel_scan/command.rb +1 -2
- data/lib/mongo/operation/shared/read_preference_supported.rb +38 -36
- data/lib/mongo/operation/shared/sessions_supported.rb +3 -2
- data/lib/mongo/protocol/msg.rb +2 -2
- data/lib/mongo/protocol/query.rb +11 -11
- data/lib/mongo/server/connection_pool.rb +0 -2
- data/lib/mongo/server.rb +0 -14
- data/lib/mongo/server_selector/secondary_preferred.rb +2 -7
- data/lib/mongo/srv/monitor.rb +0 -11
- data/lib/mongo/version.rb +1 -1
- data/spec/integration/query_cache_spec.rb +45 -0
- data/spec/integration/sdam_error_handling_spec.rb +1 -1
- data/spec/integration/sdam_events_spec.rb +3 -5
- data/spec/integration/secondary_reads_spec.rb +102 -0
- data/spec/mongo/cluster_spec.rb +2 -18
- data/spec/mongo/index/view_spec.rb +4 -2
- data/spec/mongo/operation/read_preference_legacy_spec.rb +9 -19
- data/spec/mongo/operation/read_preference_op_msg_spec.rb +3 -3
- data/spec/mongo/server/app_metadata_shared.rb +33 -7
- data/spec/mongo/server_selector/secondary_preferred_spec.rb +6 -6
- data/spec/runners/transactions/operation.rb +13 -2
- data/spec/shared/bin/get-mongodb-download-url +17 -0
- data/spec/shared/lib/mrss/cluster_config.rb +221 -0
- data/spec/shared/lib/mrss/constraints.rb +43 -0
- data/spec/shared/lib/mrss/docker_runner.rb +265 -0
- data/spec/shared/lib/mrss/lite_constraints.rb +16 -0
- data/spec/shared/lib/mrss/server_version_registry.rb +115 -0
- data/spec/shared/lib/mrss/spec_organizer.rb +3 -0
- data/spec/shared/lib/mrss/utils.rb +15 -0
- data/spec/shared/share/Dockerfile.erb +231 -0
- data/spec/shared/shlib/distro.sh +73 -0
- data/spec/shared/shlib/server.sh +290 -0
- data/spec/shared/shlib/set_env.sh +128 -0
- data/spec/solo/clean_exit_spec.rb +21 -0
- data/spec/support/client_registry.rb +8 -4
- data/spec/support/client_registry_macros.rb +4 -4
- data/spec/support/spec_config.rb +12 -0
- data/spec/support/spec_setup.rb +48 -38
- data.tar.gz.sig +0 -0
- metadata +1005 -983
- metadata.gz.sig +0 -0
@@ -684,8 +684,6 @@ module Mongo
|
|
684
684
|
# @return [ Proc ] The Finalizer.
|
685
685
|
def self.finalize(available_connections, pending_connections, populator)
|
686
686
|
proc do
|
687
|
-
populator.stop!
|
688
|
-
|
689
687
|
available_connections.each do |connection|
|
690
688
|
connection.disconnect!(reason: :pool_closed)
|
691
689
|
end
|
data/lib/mongo/server.rb
CHANGED
@@ -272,19 +272,6 @@ module Mongo
|
|
272
272
|
@connected
|
273
273
|
end
|
274
274
|
|
275
|
-
# When the server is flagged for garbage collection, stop the monitor
|
276
|
-
# thread.
|
277
|
-
#
|
278
|
-
# @example Finalize the object.
|
279
|
-
# Server.finalize(monitor)
|
280
|
-
#
|
281
|
-
# @param [ Server::Monitor ] monitor The server monitor.
|
282
|
-
#
|
283
|
-
# @since 2.2.0
|
284
|
-
def self.finalize(monitor)
|
285
|
-
proc { monitor.stop! }
|
286
|
-
end
|
287
|
-
|
288
275
|
# Start monitoring the server.
|
289
276
|
#
|
290
277
|
# Used internally by the driver to add a server to a cluster
|
@@ -297,7 +284,6 @@ module Mongo
|
|
297
284
|
Monitoring::Event::ServerOpening.new(address, cluster.topology)
|
298
285
|
)
|
299
286
|
if options[:monitoring_io] != false
|
300
|
-
ObjectSpace.define_finalizer(self, self.class.finalize(monitor))
|
301
287
|
monitor.run!
|
302
288
|
end
|
303
289
|
end
|
@@ -86,13 +86,8 @@ module Mongo
|
|
86
86
|
#
|
87
87
|
# @since 2.0.0
|
88
88
|
def to_mongos
|
89
|
-
|
90
|
-
|
91
|
-
# selector if there are no tag sets, for maximum backwards compatibility.
|
92
|
-
nil
|
93
|
-
else
|
94
|
-
to_doc
|
95
|
-
end
|
89
|
+
# Always send the read preference to mongos: DRIVERS-1642.
|
90
|
+
to_doc
|
96
91
|
end
|
97
92
|
|
98
93
|
private
|
data/lib/mongo/srv/monitor.rb
CHANGED
@@ -59,11 +59,6 @@ module Mongo
|
|
59
59
|
# records' TTL values.
|
60
60
|
attr_reader :last_result
|
61
61
|
|
62
|
-
def start!
|
63
|
-
super
|
64
|
-
ObjectSpace.define_finalizer(self, self.class.finalize(@thread))
|
65
|
-
end
|
66
|
-
|
67
62
|
private
|
68
63
|
|
69
64
|
def do_work
|
@@ -97,12 +92,6 @@ module Mongo
|
|
97
92
|
@cluster.set_server_list(last_result.address_strs)
|
98
93
|
end
|
99
94
|
|
100
|
-
def self.finalize(thread)
|
101
|
-
Proc.new do
|
102
|
-
thread.kill
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
95
|
def scan_interval
|
107
96
|
if last_result.empty?
|
108
97
|
[cluster.heartbeat_interval, MIN_SCAN_INTERVAL].min
|
data/lib/mongo/version.rb
CHANGED
@@ -1042,4 +1042,49 @@ describe 'QueryCache' do
|
|
1042
1042
|
expect(events.length).to eq(2)
|
1043
1043
|
end
|
1044
1044
|
end
|
1045
|
+
|
1046
|
+
context 'when result set has multiple documents and cursor is iterated partially' do
|
1047
|
+
|
1048
|
+
before do
|
1049
|
+
Mongo::QueryCache.enabled = false
|
1050
|
+
5.times do
|
1051
|
+
authorized_collection.insert_one({ name: 'testing' })
|
1052
|
+
end
|
1053
|
+
end
|
1054
|
+
|
1055
|
+
shared_examples 'retrieves full result set on second iteration' do
|
1056
|
+
it 'retrieves full result set on second iteration' do
|
1057
|
+
Mongo::QueryCache.clear
|
1058
|
+
Mongo::QueryCache.enabled = true
|
1059
|
+
|
1060
|
+
partial_first_iteration
|
1061
|
+
|
1062
|
+
authorized_collection.find.to_a.length.should == 5
|
1063
|
+
end
|
1064
|
+
|
1065
|
+
end
|
1066
|
+
|
1067
|
+
context 'using each & break' do
|
1068
|
+
let(:partial_first_iteration) do
|
1069
|
+
called = false
|
1070
|
+
authorized_collection.find.each do
|
1071
|
+
called = true
|
1072
|
+
break
|
1073
|
+
end
|
1074
|
+
called.should be true
|
1075
|
+
end
|
1076
|
+
|
1077
|
+
include_examples 'retrieves full result set on second iteration'
|
1078
|
+
end
|
1079
|
+
|
1080
|
+
context 'using next' do
|
1081
|
+
let(:partial_first_iteration) do
|
1082
|
+
# #next is executed in its own fiber, and query cache is disabled
|
1083
|
+
# for that operation.
|
1084
|
+
authorized_collection.find.to_enum.next
|
1085
|
+
end
|
1086
|
+
|
1087
|
+
include_examples 'retrieves full result set on second iteration'
|
1088
|
+
end
|
1089
|
+
end
|
1045
1090
|
end
|
@@ -67,10 +67,8 @@ describe 'SDAM events' do
|
|
67
67
|
started_events.length.should <= 10
|
68
68
|
|
69
69
|
succeeded_events = subscriber.select_succeeded_events(Mongo::Monitoring::Event::ServerHeartbeatSucceeded)
|
70
|
-
# Since we gracefully close the client, we expect each heartbeat
|
71
|
-
# to complete.
|
72
70
|
started_events.length.should > 1
|
73
|
-
(succeeded_events.length
|
71
|
+
(succeeded_events.length..succeeded_events.length+1).should include(started_events.length)
|
74
72
|
end
|
75
73
|
end
|
76
74
|
|
@@ -109,9 +107,9 @@ describe 'SDAM events' do
|
|
109
107
|
# There may be in-flight ismasters that don't complete, both
|
110
108
|
# regular and awaited.
|
111
109
|
started_awaited.length.should > 1
|
112
|
-
(succeeded_awaited.length
|
110
|
+
(succeeded_awaited.length..succeeded_awaited.length+1).should include(started_awaited.length)
|
113
111
|
started_regular.length.should > 1
|
114
|
-
(succeeded_regular.length
|
112
|
+
(succeeded_regular.length..succeeded_regular.length+1).should include(started_regular.length)
|
115
113
|
end
|
116
114
|
end
|
117
115
|
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'Secondary reads' do
|
4
|
+
before do
|
5
|
+
root_authorized_client.use('sr')['secondary_reads'].drop
|
6
|
+
root_authorized_client.use('sr')['secondary_reads'].insert_one(test: 1)
|
7
|
+
end
|
8
|
+
|
9
|
+
shared_examples 'performs reads as per read preference' do
|
10
|
+
|
11
|
+
%i(primary primary_preferred).each do |mode|
|
12
|
+
|
13
|
+
context mode.inspect do
|
14
|
+
|
15
|
+
let(:client) do
|
16
|
+
root_authorized_client.with(read: {mode: mode}).use('sr')
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'reads from primary' do
|
20
|
+
start_stats = get_read_counters
|
21
|
+
|
22
|
+
30.times do
|
23
|
+
client['secondary_reads'].find.to_a
|
24
|
+
end
|
25
|
+
|
26
|
+
end_stats = get_read_counters
|
27
|
+
|
28
|
+
end_stats[:secondary].should be_within(10).of(start_stats[:secondary])
|
29
|
+
end_stats[:primary].should >= start_stats[:primary] + 30
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
%i(secondary secondary_preferred).each do |mode|
|
35
|
+
|
36
|
+
context mode.inspect do
|
37
|
+
let(:client) do
|
38
|
+
root_authorized_client.with(read: {mode: mode}).use('sr')
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'reads from secondaries' do
|
42
|
+
start_stats = get_read_counters
|
43
|
+
|
44
|
+
30.times do
|
45
|
+
client['secondary_reads'].find.to_a
|
46
|
+
end
|
47
|
+
|
48
|
+
end_stats = get_read_counters
|
49
|
+
|
50
|
+
end_stats[:primary].should be_within(10).of(start_stats[:primary])
|
51
|
+
end_stats[:secondary].should >= start_stats[:secondary] + 30
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context 'replica set' do
|
58
|
+
require_topology :replica_set
|
59
|
+
|
60
|
+
include_examples 'performs reads as per read preference'
|
61
|
+
end
|
62
|
+
|
63
|
+
context 'sharded cluster' do
|
64
|
+
require_topology :sharded
|
65
|
+
|
66
|
+
include_examples 'performs reads as per read preference'
|
67
|
+
end
|
68
|
+
|
69
|
+
def get_read_counters
|
70
|
+
client = ClientRegistry.instance.global_client('root_authorized')
|
71
|
+
addresses = []
|
72
|
+
if client.cluster.sharded?
|
73
|
+
doc = client.use('admin').command(listShards: 1).documents.first
|
74
|
+
doc['shards'].each do |shard|
|
75
|
+
addresses += shard['host'].split('/').last.split(',')
|
76
|
+
end
|
77
|
+
else
|
78
|
+
client.cluster.servers.each do |server|
|
79
|
+
next unless server.primary? || server.secondary?
|
80
|
+
addresses << server.address.seed
|
81
|
+
end
|
82
|
+
end
|
83
|
+
stats = Hash.new(0)
|
84
|
+
addresses.each do |address|
|
85
|
+
ClientRegistry.instance.new_local_client(
|
86
|
+
[address],
|
87
|
+
SpecConfig.instance.all_test_options.merge(connect: :direct),
|
88
|
+
) do |c|
|
89
|
+
server = c.cluster.servers.first
|
90
|
+
next unless server.primary? || server.secondary?
|
91
|
+
stat = c.command(serverStatus: 1).documents.first
|
92
|
+
queries = stat['opcounters']['query']
|
93
|
+
if server.primary?
|
94
|
+
stats[:primary] += queries
|
95
|
+
else
|
96
|
+
stats[:secondary] += queries
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
stats
|
101
|
+
end
|
102
|
+
end
|
data/spec/mongo/cluster_spec.rb
CHANGED
@@ -274,27 +274,11 @@ describe Mongo::Cluster do
|
|
274
274
|
|
275
275
|
describe '#add' do
|
276
276
|
|
277
|
-
context 'when topology is Single' do
|
278
|
-
|
279
|
-
let(:cluster) { cluster_with_semaphore }
|
280
|
-
|
281
|
-
let(:topology) do
|
282
|
-
Mongo::Cluster::Topology::Single.new({}, cluster)
|
283
|
-
end
|
284
|
-
|
285
|
-
before do
|
286
|
-
cluster.add('a')
|
287
|
-
end
|
288
|
-
|
289
|
-
it 'does not add discovered servers to the cluster' do
|
290
|
-
expect(cluster.servers[0].address.seed).to_not eq('a')
|
291
|
-
end
|
292
|
-
end
|
293
|
-
|
294
277
|
context 'topology is Sharded' do
|
278
|
+
require_topology :sharded
|
295
279
|
|
296
280
|
let(:topology) do
|
297
|
-
Mongo::Cluster::Topology::
|
281
|
+
Mongo::Cluster::Topology::Sharded.new({}, cluster)
|
298
282
|
end
|
299
283
|
|
300
284
|
before do
|
@@ -305,7 +305,8 @@ describe Mongo::Index::View do
|
|
305
305
|
{ key: { testing: -1 }, unique: true },
|
306
306
|
{ commit_quorum: 'unsupported-value' }
|
307
307
|
)
|
308
|
-
|
308
|
+
# 4.4.4 changed the text of the error message
|
309
|
+
end.to raise_error(Mongo::Error::OperationFailure, /Commit quorum cannot be satisfied with the current replica set configuration|No write concern mode named 'unsupported-value' found in replica set configuration/)
|
309
310
|
end
|
310
311
|
end
|
311
312
|
end
|
@@ -964,7 +965,8 @@ describe Mongo::Index::View do
|
|
964
965
|
it 'raises an exception' do
|
965
966
|
expect do
|
966
967
|
view.create_one({ 'x' => 1 }, commit_quorum: 'unsupported-value')
|
967
|
-
|
968
|
+
# 4.4.4 changed the text of the error message
|
969
|
+
end.to raise_error(Mongo::Error::OperationFailure, /Commit quorum cannot be satisfied with the current replica set configuration|No write concern mode named 'unsupported-value' found in replica set configuration/)
|
968
970
|
end
|
969
971
|
end
|
970
972
|
end
|
@@ -46,10 +46,10 @@ describe Mongo::Operation::ReadPreferenceSupported do
|
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
49
|
-
describe '#
|
49
|
+
describe '#add_slave_ok_flag?' do
|
50
50
|
|
51
51
|
let(:actual) do
|
52
|
-
operation.send(:
|
52
|
+
operation.send(:add_slave_ok_flag?, connection)
|
53
53
|
end
|
54
54
|
|
55
55
|
shared_examples_for 'sets the slave_ok flag as expected' do
|
@@ -60,9 +60,7 @@ describe Mongo::Operation::ReadPreferenceSupported do
|
|
60
60
|
|
61
61
|
shared_examples_for 'never sets slave_ok' do
|
62
62
|
|
63
|
-
let(:expected)
|
64
|
-
{ }
|
65
|
-
end
|
63
|
+
let(:expected) { false }
|
66
64
|
|
67
65
|
context 'when no read preference is specified' do
|
68
66
|
let(:read_pref) { Mongo::ServerSelector.get }
|
@@ -85,9 +83,7 @@ describe Mongo::Operation::ReadPreferenceSupported do
|
|
85
83
|
|
86
84
|
shared_examples_for 'always sets slave_ok' do
|
87
85
|
|
88
|
-
let(:expected)
|
89
|
-
{ :flags => [ :slave_ok ] }
|
90
|
-
end
|
86
|
+
let(:expected) { true }
|
91
87
|
|
92
88
|
context 'when no read preference is specified' do
|
93
89
|
let(:read_pref) { Mongo::ServerSelector.get }
|
@@ -114,9 +110,7 @@ describe Mongo::Operation::ReadPreferenceSupported do
|
|
114
110
|
|
115
111
|
let(:read_pref) { Mongo::ServerSelector.get }
|
116
112
|
|
117
|
-
let(:expected)
|
118
|
-
{ }
|
119
|
-
end
|
113
|
+
let(:expected) { false }
|
120
114
|
|
121
115
|
it_behaves_like 'sets the slave_ok flag as expected'
|
122
116
|
end
|
@@ -127,9 +121,7 @@ describe Mongo::Operation::ReadPreferenceSupported do
|
|
127
121
|
|
128
122
|
let(:read_pref) { Mongo::ServerSelector.get(:mode => :secondary) }
|
129
123
|
|
130
|
-
let(:expected)
|
131
|
-
{ :flags => [ :slave_ok ] }
|
132
|
-
end
|
124
|
+
let(:expected) { true }
|
133
125
|
|
134
126
|
it_behaves_like 'sets the slave_ok flag as expected'
|
135
127
|
end
|
@@ -138,9 +130,7 @@ describe Mongo::Operation::ReadPreferenceSupported do
|
|
138
130
|
|
139
131
|
let(:read_pref) { Mongo::ServerSelector.get(:mode => :primary) }
|
140
132
|
|
141
|
-
let(:expected)
|
142
|
-
{ }
|
143
|
-
end
|
133
|
+
let(:expected) { false }
|
144
134
|
|
145
135
|
it_behaves_like 'sets the slave_ok flag as expected'
|
146
136
|
end
|
@@ -206,7 +196,7 @@ describe Mongo::Operation::ReadPreferenceSupported do
|
|
206
196
|
end
|
207
197
|
end
|
208
198
|
|
209
|
-
describe '#
|
199
|
+
describe '#add_read_preference_legacy' do
|
210
200
|
|
211
201
|
let(:read_pref) do
|
212
202
|
Mongo::ServerSelector.get(:mode => mode)
|
@@ -215,7 +205,7 @@ describe Mongo::Operation::ReadPreferenceSupported do
|
|
215
205
|
# Behavior of sending $readPreference is the same regardless of topology.
|
216
206
|
shared_examples_for '$readPreference in the command' do
|
217
207
|
let(:actual) do
|
218
|
-
operation.send(:
|
208
|
+
operation.send(:add_read_preference_legacy, operation.send(:selector), connection)
|
219
209
|
end
|
220
210
|
|
221
211
|
let(:expected_read_preference) do
|
@@ -175,13 +175,13 @@ describe Mongo::Operation::SessionsSupported do
|
|
175
175
|
let(:tag_sets) { nil }
|
176
176
|
|
177
177
|
context 'without tag_sets specified' do
|
178
|
-
it_behaves_like '
|
178
|
+
it_behaves_like 'adds read preference'
|
179
179
|
end
|
180
180
|
|
181
181
|
context 'with empty tag_sets' do
|
182
182
|
let(:tag_sets) { [] }
|
183
183
|
|
184
|
-
it_behaves_like '
|
184
|
+
it_behaves_like 'adds read preference'
|
185
185
|
end
|
186
186
|
|
187
187
|
context 'with tag_sets specified' do
|
@@ -256,7 +256,7 @@ describe Mongo::Operation::SessionsSupported do
|
|
256
256
|
let(:hedge) { nil }
|
257
257
|
|
258
258
|
context 'when tag_sets and hedge are not specified' do
|
259
|
-
it_behaves_like '
|
259
|
+
it_behaves_like 'adds read preference'
|
260
260
|
end
|
261
261
|
|
262
262
|
context 'when tag_sets are specified' do
|
@@ -8,14 +8,40 @@ shared_examples 'app metadata document' do
|
|
8
8
|
document[:client][:driver][:version].should == Mongo::VERSION
|
9
9
|
end
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
11
|
+
context 'linux' do
|
12
|
+
before(:all) do
|
13
|
+
unless SpecConfig.instance.linux?
|
14
|
+
skip "Linux required, we have #{RbConfig::CONFIG['host_os']}"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'includes operating system information' do
|
19
|
+
document[:client][:os][:type].should == 'linux'
|
20
|
+
if BSON::Environment.jruby? || RUBY_VERSION >= '3.0'
|
21
|
+
document[:client][:os][:name].should == 'linux'
|
22
|
+
else
|
23
|
+
document[:client][:os][:name].should == 'linux-gnu'
|
24
|
+
end
|
25
|
+
document[:client][:os][:architecture].should == 'x86_64'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'macos' do
|
30
|
+
before(:all) do
|
31
|
+
unless SpecConfig.instance.macos?
|
32
|
+
skip "MacOS required, we have #{RbConfig::CONFIG['host_os']}"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'includes operating system information' do
|
37
|
+
document[:client][:os][:type].should == 'darwin'
|
38
|
+
if BSON::Environment.jruby?
|
39
|
+
document[:client][:os][:name].should == 'darwin'
|
40
|
+
else
|
41
|
+
document[:client][:os][:name].should =~ /darwin\d+/
|
42
|
+
end
|
43
|
+
document[:client][:os][:architecture].should == 'x86_64'
|
17
44
|
end
|
18
|
-
document[:client][:os][:architecture].should == 'x86_64'
|
19
45
|
end
|
20
46
|
|
21
47
|
context 'mri' do
|