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.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/lib/mongo/background_thread.rb +11 -0
  4. data/lib/mongo/cluster/sdam_flow.rb +14 -0
  5. data/lib/mongo/cluster.rb +0 -26
  6. data/lib/mongo/collection/view/iterable.rb +16 -6
  7. data/lib/mongo/collection.rb +2 -0
  8. data/lib/mongo/cursor.rb +10 -0
  9. data/lib/mongo/database.rb +14 -2
  10. data/lib/mongo/grid/fs_bucket.rb +37 -37
  11. data/lib/mongo/operation/parallel_scan/command.rb +1 -2
  12. data/lib/mongo/operation/shared/read_preference_supported.rb +38 -36
  13. data/lib/mongo/operation/shared/sessions_supported.rb +3 -2
  14. data/lib/mongo/protocol/msg.rb +2 -2
  15. data/lib/mongo/protocol/query.rb +11 -11
  16. data/lib/mongo/server/connection_pool.rb +0 -2
  17. data/lib/mongo/server.rb +0 -14
  18. data/lib/mongo/server_selector/secondary_preferred.rb +2 -7
  19. data/lib/mongo/srv/monitor.rb +0 -11
  20. data/lib/mongo/version.rb +1 -1
  21. data/spec/integration/query_cache_spec.rb +45 -0
  22. data/spec/integration/sdam_error_handling_spec.rb +1 -1
  23. data/spec/integration/sdam_events_spec.rb +3 -5
  24. data/spec/integration/secondary_reads_spec.rb +102 -0
  25. data/spec/mongo/cluster_spec.rb +2 -18
  26. data/spec/mongo/index/view_spec.rb +4 -2
  27. data/spec/mongo/operation/read_preference_legacy_spec.rb +9 -19
  28. data/spec/mongo/operation/read_preference_op_msg_spec.rb +3 -3
  29. data/spec/mongo/server/app_metadata_shared.rb +33 -7
  30. data/spec/mongo/server_selector/secondary_preferred_spec.rb +6 -6
  31. data/spec/runners/transactions/operation.rb +13 -2
  32. data/spec/shared/bin/get-mongodb-download-url +17 -0
  33. data/spec/shared/lib/mrss/cluster_config.rb +221 -0
  34. data/spec/shared/lib/mrss/constraints.rb +43 -0
  35. data/spec/shared/lib/mrss/docker_runner.rb +265 -0
  36. data/spec/shared/lib/mrss/lite_constraints.rb +16 -0
  37. data/spec/shared/lib/mrss/server_version_registry.rb +115 -0
  38. data/spec/shared/lib/mrss/spec_organizer.rb +3 -0
  39. data/spec/shared/lib/mrss/utils.rb +15 -0
  40. data/spec/shared/share/Dockerfile.erb +231 -0
  41. data/spec/shared/shlib/distro.sh +73 -0
  42. data/spec/shared/shlib/server.sh +290 -0
  43. data/spec/shared/shlib/set_env.sh +128 -0
  44. data/spec/solo/clean_exit_spec.rb +21 -0
  45. data/spec/support/client_registry.rb +8 -4
  46. data/spec/support/client_registry_macros.rb +4 -4
  47. data/spec/support/spec_config.rb +12 -0
  48. data/spec/support/spec_setup.rb +48 -38
  49. data.tar.gz.sig +0 -0
  50. metadata +1005 -983
  51. 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
- if tag_sets.empty? && max_staleness.nil? && hedge.nil?
90
- # The server preference is not sent to mongos as part of the query
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
@@ -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
@@ -17,5 +17,5 @@ module Mongo
17
17
  # The current version of the driver.
18
18
  #
19
19
  # @since 2.0.0
20
- VERSION = '2.14.0'.freeze
20
+ VERSION = '2.14.1'.freeze
21
21
  end
@@ -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
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe 'SDAM error handling' do
4
- clean_slate_for_all
4
+ clean_slate
5
5
 
6
6
  after do
7
7
  # Close all clients after every test to avoid leaking expectations into
@@ -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-1..succeeded_events.length).should include(started_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-1..succeeded_awaited.length).should include(started_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-1..succeeded_regular.length).should include(started_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
@@ -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::Single.new({}, cluster)
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
- end.to raise_error(Mongo::Error::OperationFailure, /Commit quorum cannot be satisfied with the current replica set configuration/)
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
- end.to raise_error(Mongo::Error::OperationFailure, /Commit quorum cannot be satisfied with the current replica set configuration/)
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 '#add_slave_ok_flag_maybe' do
49
+ describe '#add_slave_ok_flag?' do
50
50
 
51
51
  let(:actual) do
52
- operation.send(:add_slave_ok_flag_maybe, operation.send(:options), connection)
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) do
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) do
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) do
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) do
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) do
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 '#update_selector_for_read_pref' do
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(:update_selector_for_read_pref, operation.send(:selector), connection)
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 'does not modify selector'
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 'does not modify selector'
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 'does not modify selector'
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
- it 'includes operating system information' do
12
- document[:client][:os][:type].should == 'linux'
13
- if BSON::Environment.jruby? || RUBY_VERSION >= '3.0'
14
- document[:client][:os][:name].should == 'linux'
15
- else
16
- document[:client][:os][:name].should == 'linux-gnu'
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