mongo 2.11.0 → 2.11.1

Sign up to get free protection for your applications and to get access to all the features.
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