mongo 2.11.0 → 2.11.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d27047092172489df2f36b02e09050990a7aae2685a055bf4a30d33a43b86325
4
- data.tar.gz: 0f14e016a1dbae9ccda55d77927a773d58a10967b959b9480b052c2df9410386
3
+ metadata.gz: 33db1e0c2cfe7d7de3da0fbc3b24deac1ab01c0ad3cfc07239616bda20bd3e21
4
+ data.tar.gz: 6923e1d8fff7313a7f1a5a73e5a23fcebc6fa9b2b3d083e7f7468928ff2d76f1
5
5
  SHA512:
6
- metadata.gz: 3cf2e4bfd5860003b7131c72fae1b58a0a56906a73d67e9e08c465cd5cf0b79f99af431e55597733f3baf9d68a9617cec47647d4bb7b9c8e84eedeeff96509b9
7
- data.tar.gz: 190be385cbcfdae0293448281010b8d6c4ca785b37236fe57362921eaeb7cfdb5115dd0159e51622946b97170fa105a375fd0a73ceb4600b268e599aa687dcf1
6
+ metadata.gz: 415ae16f9f26a04e7ed9d9d29f264f2632a8cfca230849a11152f8bc62a722aa4a7e600ca5db217e26e695ca2b270a54973bb9c339af67f1f3880c67ed917cc4
7
+ data.tar.gz: '058ec4695e331e142f99feee1a59082494ed91e80d55490985e8eee650f1d94ba767d581ea08180ccff18c93300642ea59ca91dc1fe44da6771fd4ca2a94d27f'
checksums.yaml.gz.sig CHANGED
Binary file
data.tar.gz.sig CHANGED
Binary file
@@ -119,7 +119,12 @@ module Mongo
119
119
  legacy_read_with_retry(session, server_selector, &block)
120
120
  else
121
121
  server = select_server(cluster, server_selector, session)
122
- yield server
122
+ begin
123
+ yield server
124
+ rescue Error::SocketError, Error::SocketTimeoutError, Error::OperationFailure => e
125
+ e.add_note('retries disabled')
126
+ raise e
127
+ end
123
128
  end
124
129
  end
125
130
 
@@ -214,12 +219,14 @@ module Mongo
214
219
  begin
215
220
  yield(server, txn_num, false)
216
221
  rescue Error::SocketError, Error::SocketTimeoutError => e
222
+ e.add_note('modern retry')
217
223
  e.add_note("attempt 1")
218
224
  if session.in_transaction? && !ending_transaction
219
225
  raise e
220
226
  end
221
227
  retry_write(e, session, txn_num, &block)
222
228
  rescue Error::OperationFailure => e
229
+ e.add_note('modern retry')
223
230
  e.add_note("attempt 1")
224
231
  if e.unsupported_retryable_write?
225
232
  raise_unsupported_error(e)
@@ -250,7 +257,12 @@ module Mongo
250
257
  def nro_write_with_retry(session, write_concern, &block)
251
258
  if session && session.client.options[:retry_writes]
252
259
  server = select_server(cluster, ServerSelector.primary, session)
253
- yield server
260
+ begin
261
+ yield server
262
+ rescue Error::SocketError, Error::SocketTimeoutError, Error::OperationFailure => e
263
+ e.add_note('retries disabled')
264
+ raise e
265
+ end
254
266
  else
255
267
  legacy_write_with_retry(nil, session, &block)
256
268
  end
@@ -280,7 +292,8 @@ module Mongo
280
292
  server ||= select_server(cluster, ServerSelector.primary, session)
281
293
  yield server
282
294
  rescue Error::OperationFailure => e
283
- e.add_note("attempt #{attempt + 1}")
295
+ e.add_note('legacy retry')
296
+ e.add_note("attempt #{attempt}")
284
297
  server = nil
285
298
  if attempt > client.max_write_retries
286
299
  raise e
@@ -298,18 +311,19 @@ module Mongo
298
311
  private
299
312
 
300
313
  def modern_read_with_retry(session, server_selector, &block)
301
- attempt = 0
302
314
  server = select_server(cluster, server_selector, session)
303
315
  begin
304
316
  yield server
305
317
  rescue Error::SocketError, Error::SocketTimeoutError => e
306
- e.add_note("attempt #{attempt + 1}")
318
+ e.add_note('modern retry')
319
+ e.add_note("attempt 1")
307
320
  if session.in_transaction?
308
321
  raise e
309
322
  end
310
323
  retry_read(e, server_selector, session, &block)
311
324
  rescue Error::OperationFailure => e
312
- e.add_note("attempt #{attempt + 1}")
325
+ e.add_note('modern retry')
326
+ e.add_note("attempt 1")
313
327
  if session.in_transaction? || !e.write_retryable?
314
328
  raise e
315
329
  end
@@ -324,7 +338,8 @@ module Mongo
324
338
  attempt += 1
325
339
  yield server
326
340
  rescue Error::SocketError, Error::SocketTimeoutError => e
327
- e.add_note("attempt #{attempt + 1}")
341
+ e.add_note('legacy retry')
342
+ e.add_note("attempt #{attempt}")
328
343
  if attempt > client.max_read_retries || (session && session.in_transaction?)
329
344
  raise e
330
345
  end
@@ -332,7 +347,8 @@ module Mongo
332
347
  server = select_server(cluster, server_selector, session)
333
348
  retry
334
349
  rescue Error::OperationFailure => e
335
- e.add_note("attempt #{attempt + 1}")
350
+ e.add_note('legacy retry')
351
+ e.add_note("attempt #{attempt}")
336
352
  if e.retryable? && !(session && session.in_transaction?)
337
353
  if attempt > client.max_read_retries
338
354
  raise e
@@ -375,9 +391,11 @@ module Mongo
375
391
  begin
376
392
  yield server, true
377
393
  rescue Error::SocketError, Error::SocketTimeoutError => e
394
+ e.add_note('modern retry')
378
395
  e.add_note("attempt 2")
379
396
  raise e
380
397
  rescue Error::OperationFailure => e
398
+ e.add_note('modern retry')
381
399
  unless e.write_retryable?
382
400
  original_error.add_note("later retry failed: #{e.class}: #{e}")
383
401
  raise original_error
@@ -385,6 +403,7 @@ module Mongo
385
403
  e.add_note("attempt 2")
386
404
  raise e
387
405
  rescue => e
406
+ e.add_note('modern retry')
388
407
  original_error.add_note("later retry failed: #{e.class}: #{e}")
389
408
  raise original_error
390
409
  end
@@ -398,15 +417,19 @@ module Mongo
398
417
  # server unknown). Here we just need to wait for server selection.
399
418
  server = select_server(cluster, ServerSelector.primary, session)
400
419
  unless server.retry_writes?
420
+ # Do not need to add "modern retry" here, it should already be on
421
+ # the first exception.
401
422
  original_error.add_note('did not retry because server selected for retry does not supoprt retryable writes')
402
423
  raise original_error
403
424
  end
404
425
  log_retry(original_error, message: 'Write retry')
405
426
  yield(server, txn_num, true)
406
427
  rescue Error::SocketError, Error::SocketTimeoutError => e
428
+ e.add_note('modern retry')
407
429
  e.add_note('attempt 2')
408
430
  raise e
409
431
  rescue Error::OperationFailure => e
432
+ e.add_note('modern retry')
410
433
  if e.write_retryable?
411
434
  e.add_note('attempt 2')
412
435
  raise e
@@ -415,6 +438,8 @@ module Mongo
415
438
  raise original_error
416
439
  end
417
440
  rescue => e
441
+ # Do not need to add "modern retry" here, it should already be on
442
+ # the first exception.
418
443
  original_error.add_note("later retry failed: #{e.class}: #{e}")
419
444
  raise original_error
420
445
  end
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.11.0'.freeze
20
+ VERSION = '2.11.1'.freeze
21
21
  end
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe 'Retryable writes tests' do
3
+ describe 'Failing retryable operations' do
4
4
  # Requirement for fail point
5
5
  min_server_fcv '4.0'
6
6
 
@@ -9,22 +9,12 @@ describe 'Retryable writes tests' do
9
9
  end
10
10
 
11
11
  let(:collection) do
12
- client['retryable-writes-error-spec']
12
+ client['retryable-errors-spec']
13
13
  end
14
14
 
15
- context 'when retry fails' do
15
+ context 'when operation fails' do
16
16
  require_topology :replica_set
17
17
 
18
- let(:fail_point_command) do
19
- {
20
- configureFailPoint: 'failCommand',
21
- mode: {times: 1},
22
- data: {
23
- failCommands: ['find'],
24
- errorCode: 11600,
25
- },
26
- }
27
- end
28
18
 
29
19
  let(:clear_fail_point_command) do
30
20
  {
@@ -40,11 +30,7 @@ describe 'Retryable writes tests' do
40
30
  end
41
31
 
42
32
  let(:collection) do
43
- client['retryable-writes-error-spec', read: {mode: :secondary_preferred}]
44
- end
45
-
46
- let(:events) do
47
- events = EventSubscriber.command_started_events('find')
33
+ client['retryable-errors-spec', read: {mode: :secondary_preferred}]
48
34
  end
49
35
 
50
36
  let(:first_server) do
@@ -59,41 +45,220 @@ describe 'Retryable writes tests' do
59
45
  end
60
46
  end
61
47
 
62
- let(:perform_read) do
63
- client.cluster.servers_list.each do |server|
64
- server.monitor.stop!
48
+ shared_context 'read operation' do
49
+ let(:fail_point_command) do
50
+ {
51
+ configureFailPoint: 'failCommand',
52
+ mode: {times: 1},
53
+ data: {
54
+ failCommands: ['find'],
55
+ errorCode: 11600,
56
+ },
57
+ }
65
58
  end
66
59
 
67
- ClusterTools.instance.direct_client_for_each_server do |client|
60
+ let(:set_fail_point) do
61
+ client.cluster.servers_list.each do |server|
62
+ server.monitor.stop!
63
+ end
64
+
65
+ ClusterTools.instance.direct_client_for_each_server do |client|
66
+ client.use(:admin).database.command(fail_point_command)
67
+ end
68
+ end
69
+
70
+ let(:operation_exception) do
71
+ set_fail_point
72
+
73
+ begin
74
+ collection.find(a: 1).to_a
75
+ rescue Mongo::Error::OperationFailure => exception
76
+ else
77
+ fail('Expected operation to fail')
78
+ end
79
+
80
+ puts exception.message
81
+
82
+ exception
83
+ end
84
+
85
+ let(:events) do
86
+ EventSubscriber.command_started_events('find')
87
+ end
88
+ end
89
+
90
+ shared_context 'write operation' do
91
+ let(:fail_point_command) do
92
+ {
93
+ configureFailPoint: 'failCommand',
94
+ mode: {times: 2},
95
+ data: {
96
+ failCommands: ['insert'],
97
+ errorCode: 11600,
98
+ },
99
+ }
100
+ end
101
+
102
+ let(:set_fail_point) do
68
103
  client.use(:admin).database.command(fail_point_command)
69
104
  end
70
105
 
71
- begin
72
- collection.find(a: 1).to_a
73
- rescue Mongo::Error::OperationFailure => @exception
74
- else
75
- fail('Expected operation to fail')
106
+ let(:operation_exception) do
107
+ set_fail_point
108
+
109
+ begin
110
+ collection.insert_one(a: 1)
111
+ rescue Mongo::Error::OperationFailure => exception
112
+ else
113
+ fail('Expected operation to fail')
114
+ end
115
+
116
+ #puts exception.message
117
+
118
+ exception
119
+ end
120
+
121
+ let(:events) do
122
+ EventSubscriber.command_started_events('insert')
123
+ end
124
+ end
125
+
126
+ shared_examples_for 'failing retry' do
127
+
128
+ it 'indicates second attempt' do
129
+ expect(operation_exception.message).to include('attempt 2')
130
+ expect(operation_exception.message).not_to include('attempt 1')
131
+ expect(operation_exception.message).not_to include('attempt 3')
76
132
  end
77
133
 
78
- puts @exception.message
134
+ it 'publishes two events' do
79
135
 
80
- expect(events.length).to eq(2)
81
- expect(events.first.address.seed).not_to eq(events.last.address.seed)
136
+ expect(events.length).to eq(2)
137
+ end
82
138
  end
83
139
 
84
- it 'is reported on the server of the second attempt' do
85
- perform_read
140
+ shared_examples_for 'failing single attempt' do
141
+
142
+ it 'does not indicate attempt' do
143
+ expect(operation_exception.message).not_to include('attempt 1')
144
+ expect(operation_exception.message).not_to include('attempt 2')
145
+ expect(operation_exception.message).not_to include('attempt 3')
146
+ end
86
147
 
87
- expect(@exception.message).not_to include(first_server.address.seed)
88
- expect(@exception.message).to include(second_server.address.seed)
148
+ it 'publishes one event' do
149
+
150
+ expect(events.length).to eq(1)
151
+ end
89
152
  end
90
153
 
91
- it 'marks servers used in both attempts unknown' do
92
- perform_read
154
+ shared_examples_for 'failing retry on the same server' do
155
+ it 'is reported on the server of the second attempt' do
156
+ expect(operation_exception.message).to include(second_server.address.seed)
157
+ end
158
+ end
159
+
160
+ shared_examples_for 'failing retry on a different server' do
161
+ it 'is reported on the server of the second attempt' do
162
+ expect(operation_exception.message).not_to include(first_server.address.seed)
163
+ expect(operation_exception.message).to include(second_server.address.seed)
164
+ end
93
165
 
94
- expect(first_server).to be_unknown
166
+ it 'marks servers used in both attempts unknown' do
167
+ operation_exception
95
168
 
96
- expect(second_server).to be_unknown
169
+ expect(first_server).to be_unknown
170
+
171
+ expect(second_server).to be_unknown
172
+ end
173
+
174
+ it 'publishes events for the different server addresses' do
175
+
176
+ expect(events.length).to eq(2)
177
+ expect(events.first.address.seed).not_to eq(events.last.address.seed)
178
+ end
179
+ end
180
+
181
+ shared_examples_for 'modern retry' do
182
+ it 'indicates modern retry' do
183
+ expect(operation_exception.message).to include('modern retry')
184
+ expect(operation_exception.message).not_to include('legacy retry')
185
+ expect(operation_exception.message).not_to include('retries disabled')
186
+ end
187
+ end
188
+
189
+ shared_examples_for 'legacy retry' do
190
+ it 'indicates legacy retry' do
191
+ expect(operation_exception.message).to include('legacy retry')
192
+ expect(operation_exception.message).not_to include('modern retry')
193
+ expect(operation_exception.message).not_to include('retries disabled')
194
+ end
195
+ end
196
+
197
+ shared_examples_for 'disabled retry' do
198
+ it 'indicates retries are disabled' do
199
+ expect(operation_exception.message).to include('retries disabled')
200
+ expect(operation_exception.message).not_to include('legacy retry')
201
+ expect(operation_exception.message).not_to include('modern retry')
202
+ end
203
+ end
204
+
205
+ context 'when read is retried and retry fails' do
206
+ include_context 'read operation'
207
+
208
+ context 'modern read retries' do
209
+ require_wired_tiger_on_36
210
+
211
+ let(:client) do
212
+ subscribed_client.with(retry_reads: true)
213
+ end
214
+
215
+ it_behaves_like 'failing retry'
216
+ it_behaves_like 'modern retry'
217
+ end
218
+
219
+ context 'legacy read retries' do
220
+ let(:client) do
221
+ subscribed_client.with(retry_reads: false, read_retry_interval: 0)
222
+ end
223
+
224
+ it_behaves_like 'failing retry'
225
+ it_behaves_like 'legacy retry'
226
+ end
227
+ end
228
+
229
+ context 'when read retries are disabled' do
230
+ let(:client) do
231
+ subscribed_client.with(retry_reads: false, max_read_retries: 0)
232
+ end
233
+
234
+ include_context 'read operation'
235
+
236
+ it_behaves_like 'failing single attempt'
237
+ it_behaves_like 'disabled retry'
238
+ end
239
+
240
+ context 'when write is retried and retry fails' do
241
+ include_context 'write operation'
242
+
243
+ context 'modern write retries' do
244
+ require_wired_tiger_on_36
245
+
246
+ let(:client) do
247
+ subscribed_client.with(retry_writes: true)
248
+ end
249
+
250
+ it_behaves_like 'failing retry'
251
+ it_behaves_like 'modern retry'
252
+ end
253
+
254
+ context 'legacy write' do
255
+ let(:client) do
256
+ subscribed_client.with(retry_writes: false)
257
+ end
258
+
259
+ it_behaves_like 'failing retry'
260
+ it_behaves_like 'legacy retry'
261
+ end
97
262
  end
98
263
  end
99
264
  end