moped 2.0.3 → 2.0.7
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
- data/CHANGELOG.md +24 -0
- data/lib/moped/address.rb +19 -5
- data/lib/moped/collection.rb +7 -3
- data/lib/moped/connection/manager.rb +9 -2
- data/lib/moped/connection.rb +10 -9
- data/lib/moped/cursor.rb +7 -4
- data/lib/moped/errors.rb +4 -3
- data/lib/moped/failover/retry.rb +4 -2
- data/lib/moped/failover.rb +2 -1
- data/lib/moped/loggable.rb +4 -0
- data/lib/moped/node.rb +24 -9
- data/lib/moped/operation/read.rb +20 -3
- data/lib/moped/protocol/message.rb +10 -8
- data/lib/moped/query.rb +31 -24
- data/lib/moped/read_preference/selectable.rb +2 -35
- data/lib/moped/retryable.rb +46 -0
- data/lib/moped/version.rb +1 -1
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: eda09d3428a61f892b3d983486b0bcacb4d22c1f
|
4
|
+
data.tar.gz: 0d496810ace691461b3443f1163102a76f85ec5b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 951ba327262a778af25d190b5f80332c10bac5f8186194c399091bb924bcab9c625f4b317d3807390a2fc233f3c2f2a7cfb1f499045363743ec2e6a789581043
|
7
|
+
data.tar.gz: 8a5fcdd582261c79a7d1fd241d17ffd437bd4232e3a663e040c316fa8c2bc29e15c56399fa2e677e8971c1687cbbafd8743ba4fc6af6b1c97eb888ca1a4d6c56
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,29 @@
|
|
1
1
|
# Overview
|
2
2
|
|
3
|
+
## 2.0.7
|
4
|
+
|
5
|
+
* Improved Moped Failover (John Hyman)
|
6
|
+
|
7
|
+
## 2.0.6
|
8
|
+
|
9
|
+
* Relaxing BSON dependency to allow for 3.1.0 upgrade.
|
10
|
+
|
11
|
+
## 2.0.5
|
12
|
+
|
13
|
+
### Resolved Issues
|
14
|
+
|
15
|
+
* \#351
|
16
|
+
Fixing retries with authentication. (Wandenberg Peixoto)
|
17
|
+
|
18
|
+
* Bump BSON dependency to 3.0.4
|
19
|
+
|
20
|
+
## 2.0.4
|
21
|
+
|
22
|
+
### Resolved Issues
|
23
|
+
|
24
|
+
* \#345
|
25
|
+
Writes fail with ConnectionPool::PoolShuttingDownError. (fedenusy, dblock)
|
26
|
+
|
3
27
|
## 2.0.3
|
4
28
|
|
5
29
|
### Resolved Issues
|
data/lib/moped/address.rb
CHANGED
@@ -45,9 +45,13 @@ module Moped
|
|
45
45
|
#
|
46
46
|
# @since 2.0.0
|
47
47
|
def resolve(node)
|
48
|
+
return @resolved if @resolved
|
49
|
+
start = Time.now
|
50
|
+
retries = 0
|
48
51
|
begin
|
49
|
-
|
50
|
-
Timeout
|
52
|
+
# This timeout should be very large since Timeout::timeout plays very badly with multithreaded code
|
53
|
+
# TODO: Remove this Timeout entirely
|
54
|
+
Timeout::timeout(@timeout * 10) do
|
51
55
|
Resolv.each_address(host) do |ip|
|
52
56
|
if ip =~ Resolv::IPv4::Regex
|
53
57
|
@ip ||= ip
|
@@ -57,9 +61,19 @@ module Moped
|
|
57
61
|
raise Resolv::ResolvError unless @ip
|
58
62
|
end
|
59
63
|
@resolved = "#{ip}:#{port}"
|
60
|
-
rescue Timeout::Error, Resolv::ResolvError, SocketError
|
61
|
-
|
62
|
-
|
64
|
+
rescue Timeout::Error, Resolv::ResolvError, SocketError => e
|
65
|
+
msg = [" MOPED:", "Could not resolve IP for: #{original}, delta is #{Time.now - start}, error class is #{e.inspect}, retries is #{retries}. Node is #{node.inspect}", "n/a"]
|
66
|
+
if retries == 0
|
67
|
+
Loggable.info(*msg)
|
68
|
+
else
|
69
|
+
Loggable.warn(*msg)
|
70
|
+
end
|
71
|
+
if retries < 2
|
72
|
+
retries += 1
|
73
|
+
retry
|
74
|
+
else
|
75
|
+
node.down! and false
|
76
|
+
end
|
63
77
|
end
|
64
78
|
end
|
65
79
|
end
|
data/lib/moped/collection.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
require "moped/query"
|
3
|
+
require "moped/retryable"
|
3
4
|
|
4
5
|
module Moped
|
5
6
|
|
@@ -8,6 +9,7 @@ module Moped
|
|
8
9
|
# @since 1.0.0
|
9
10
|
class Collection
|
10
11
|
include Readable
|
12
|
+
include Retryable
|
11
13
|
|
12
14
|
# @!attribute database
|
13
15
|
# @return [ Database ] The database for the collection.
|
@@ -120,9 +122,11 @@ module Moped
|
|
120
122
|
#
|
121
123
|
# @since 1.0.0
|
122
124
|
def insert(documents, flags = nil)
|
123
|
-
|
124
|
-
|
125
|
-
|
125
|
+
with_retry(cluster) do
|
126
|
+
docs = documents.is_a?(Array) ? documents : [ documents ]
|
127
|
+
cluster.with_primary do |node|
|
128
|
+
node.insert(database.name, name, docs, write_concern, flags: flags || [])
|
129
|
+
end
|
126
130
|
end
|
127
131
|
end
|
128
132
|
|
@@ -48,10 +48,17 @@ module Moped
|
|
48
48
|
#
|
49
49
|
# @since 2.0.3
|
50
50
|
def shutdown(node)
|
51
|
+
pool = nil
|
51
52
|
MUTEX.synchronize do
|
52
53
|
pool = pools.delete(node.address.resolved)
|
53
|
-
|
54
|
-
|
54
|
+
end
|
55
|
+
pool.shutdown{ |conn| conn.disconnect } if pool
|
56
|
+
nil
|
57
|
+
end
|
58
|
+
|
59
|
+
def delete_pool(node)
|
60
|
+
MUTEX.synchronize do
|
61
|
+
pools.delete(node.address.resolved)
|
55
62
|
end
|
56
63
|
end
|
57
64
|
|
data/lib/moped/connection.rb
CHANGED
@@ -3,7 +3,6 @@ require "moped/connection/manager"
|
|
3
3
|
require "moped/connection/sockets"
|
4
4
|
|
5
5
|
module Moped
|
6
|
-
|
7
6
|
# This class contains behaviour of database socket connections.
|
8
7
|
#
|
9
8
|
# @since 2.0.0
|
@@ -15,6 +14,8 @@ module Moped
|
|
15
14
|
# @since 2.0.0
|
16
15
|
TIMEOUT = 5
|
17
16
|
|
17
|
+
REPLY_DECODE_STR = 'l<5q<l<2'
|
18
|
+
|
18
19
|
# @!attribute host
|
19
20
|
# @return [ String ] The ip address of the host.
|
20
21
|
# @!attribute options
|
@@ -114,15 +115,15 @@ module Moped
|
|
114
115
|
with_connection do |socket|
|
115
116
|
reply = Protocol::Reply.allocate
|
116
117
|
data = read_data(socket, 36)
|
117
|
-
response = data.unpack(
|
118
|
+
response = data.unpack(REPLY_DECODE_STR)
|
118
119
|
reply.length,
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
120
|
+
reply.request_id,
|
121
|
+
reply.response_to,
|
122
|
+
reply.op_code,
|
123
|
+
reply.flags,
|
124
|
+
reply.cursor_id,
|
125
|
+
reply.offset,
|
126
|
+
reply.count = response
|
126
127
|
|
127
128
|
if reply.count == 0
|
128
129
|
reply.documents = []
|
data/lib/moped/cursor.rb
CHANGED
@@ -6,6 +6,7 @@ module Moped
|
|
6
6
|
class Cursor
|
7
7
|
include Readable
|
8
8
|
include Enumerable
|
9
|
+
include Retryable
|
9
10
|
|
10
11
|
# @attribute [r] get_more_op The get more message.
|
11
12
|
# @attribute [r] kill_cursor_op The kill cursor message.
|
@@ -43,10 +44,12 @@ module Moped
|
|
43
44
|
#
|
44
45
|
# @since 1.0.0
|
45
46
|
def get_more
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
47
|
+
with_retry(session.cluster) do
|
48
|
+
reply = @node.get_more @database, @collection, @cursor_id, request_limit
|
49
|
+
@limit -= reply.count if limited?
|
50
|
+
@cursor_id = reply.cursor_id
|
51
|
+
reply.documents
|
52
|
+
end
|
50
53
|
end
|
51
54
|
|
52
55
|
# Determine the request limit for the query
|
data/lib/moped/errors.rb
CHANGED
@@ -112,10 +112,10 @@ module Moped
|
|
112
112
|
class PotentialReconfiguration < MongoError
|
113
113
|
|
114
114
|
# Not master error codes.
|
115
|
-
NOT_MASTER = [ 13435, 13436, 10009 ]
|
115
|
+
NOT_MASTER = [ 13435, 13436, 10009, 15986, 83 ]
|
116
116
|
|
117
117
|
# Error codes received around reconfiguration
|
118
|
-
CONNECTION_ERRORS_RECONFIGURATION = [ 15988, 10276, 11600, 9001, 13639, 10009, 11002 ]
|
118
|
+
CONNECTION_ERRORS_RECONFIGURATION = [ 15988, 10276, 11600, 9001, 13639, 10009, 11002, 7 ]
|
119
119
|
|
120
120
|
# Replica set reconfigurations can be either in the form of an operation
|
121
121
|
# error with code 13435, or with an error message stating the server is
|
@@ -126,7 +126,8 @@ module Moped
|
|
126
126
|
end
|
127
127
|
|
128
128
|
def connection_failure?
|
129
|
-
|
129
|
+
err = details["err"] || details["errmsg"] || details["$err"] || ""
|
130
|
+
CONNECTION_ERRORS_RECONFIGURATION.include?(details["code"]) || err.include?("could not get last error") || err.include?("connection attempt failed")
|
130
131
|
end
|
131
132
|
|
132
133
|
# Is the error due to a namespace not being found?
|
data/lib/moped/failover/retry.rb
CHANGED
@@ -9,7 +9,7 @@ module Moped
|
|
9
9
|
module Retry
|
10
10
|
extend self
|
11
11
|
|
12
|
-
# Executes the failover strategy. In the case of
|
12
|
+
# Executes the failover strategy. In the case of retry, we disconnect and
|
13
13
|
# reconnect, then try the operation one more time.
|
14
14
|
#
|
15
15
|
# @example Execute the retry strategy.
|
@@ -24,11 +24,13 @@ module Moped
|
|
24
24
|
#
|
25
25
|
# @since 2.0.0
|
26
26
|
def execute(exception, node)
|
27
|
-
node.disconnect
|
27
|
+
node.disconnect unless exception.is_a?(Errors::PoolTimeout)
|
28
28
|
begin
|
29
29
|
node.connection do |conn|
|
30
30
|
yield(conn) if block_given?
|
31
31
|
end
|
32
|
+
rescue Errors::PoolTimeout => e
|
33
|
+
raise Errors::ConnectionFailure.new e
|
32
34
|
rescue Exception => e
|
33
35
|
node.down!
|
34
36
|
raise(e)
|
data/lib/moped/failover.rb
CHANGED
@@ -21,7 +21,8 @@ module Moped
|
|
21
21
|
Errors::ConnectionFailure => Retry,
|
22
22
|
Errors::CursorNotFound => Ignore,
|
23
23
|
Errors::OperationFailure => Reconfigure,
|
24
|
-
Errors::QueryFailure => Reconfigure
|
24
|
+
Errors::QueryFailure => Reconfigure,
|
25
|
+
Errors::PoolTimeout => Retry
|
25
26
|
}.freeze
|
26
27
|
|
27
28
|
# Get the appropriate failover handler given the provided exception.
|
data/lib/moped/loggable.rb
CHANGED
@@ -42,6 +42,10 @@ module Moped
|
|
42
42
|
Moped.logger.debug([ prefix, payload, "runtime: #{runtime}" ].join(' '))
|
43
43
|
end
|
44
44
|
|
45
|
+
def self.info(prefix, payload, runtime)
|
46
|
+
Moped.logger.info([ prefix, payload, "runtime: #{runtime}" ].join(' '))
|
47
|
+
end
|
48
|
+
|
45
49
|
# Log the payload to warn.
|
46
50
|
#
|
47
51
|
# @example Log to warn.
|
data/lib/moped/node.rb
CHANGED
@@ -111,8 +111,19 @@ module Moped
|
|
111
111
|
#
|
112
112
|
# @since 2.0.0
|
113
113
|
def connection
|
114
|
-
|
115
|
-
|
114
|
+
connection_acquired = false
|
115
|
+
begin
|
116
|
+
pool.with do |conn|
|
117
|
+
connection_acquired = true
|
118
|
+
yield(conn)
|
119
|
+
end
|
120
|
+
rescue Timeout::Error, ConnectionPool::PoolShuttingDownError => e
|
121
|
+
if e.kind_of?(ConnectionPool::PoolShuttingDownError)
|
122
|
+
@pool = nil
|
123
|
+
Connection::Manager.delete_pool(self)
|
124
|
+
raise Errors::PoolTimeout.new(e)
|
125
|
+
end
|
126
|
+
raise connection_acquired ? e : Errors::PoolTimeout.new(e)
|
116
127
|
end
|
117
128
|
end
|
118
129
|
|
@@ -150,10 +161,10 @@ module Moped
|
|
150
161
|
#
|
151
162
|
# @since 2.0.0
|
152
163
|
def down!
|
153
|
-
@pool = Connection::Manager.shutdown(self)
|
154
164
|
@down_at = Time.new
|
165
|
+
@pool = nil
|
155
166
|
@latency = nil
|
156
|
-
|
167
|
+
Connection::Manager.shutdown(self)
|
157
168
|
end
|
158
169
|
|
159
170
|
# Yields the block if a connection can be established, retrying when a
|
@@ -182,6 +193,10 @@ module Moped
|
|
182
193
|
yield(conn)
|
183
194
|
end
|
184
195
|
rescue Exception => e
|
196
|
+
if e.kind_of?(ConnectionPool::PoolShuttingDownError)
|
197
|
+
@pool = nil
|
198
|
+
Connection::Manager.delete_pool(self)
|
199
|
+
end
|
185
200
|
Failover.get(e).execute(e, self, &block)
|
186
201
|
ensure
|
187
202
|
end_execution(:connection)
|
@@ -198,7 +213,7 @@ module Moped
|
|
198
213
|
#
|
199
214
|
# @return [ nil ] nil.
|
200
215
|
#
|
201
|
-
# @since 1.0.
|
216
|
+
# @since 1.0.0s
|
202
217
|
def ensure_primary
|
203
218
|
execute(:ensure_primary) do
|
204
219
|
yield(self)
|
@@ -585,14 +600,14 @@ module Moped
|
|
585
600
|
def flush(ops = queue)
|
586
601
|
operations, callbacks = ops.transpose
|
587
602
|
logging(operations) do
|
588
|
-
replies = nil
|
589
603
|
ensure_connected do |conn|
|
590
604
|
conn.write(operations)
|
591
605
|
replies = conn.receive_replies(operations)
|
606
|
+
|
607
|
+
replies.zip(callbacks).map do |reply, callback|
|
608
|
+
callback ? callback[reply] : reply
|
609
|
+
end.last
|
592
610
|
end
|
593
|
-
replies.zip(callbacks).map do |reply, callback|
|
594
|
-
callback ? callback[reply] : reply
|
595
|
-
end.last
|
596
611
|
end
|
597
612
|
ensure
|
598
613
|
ops.clear
|
data/lib/moped/operation/read.rb
CHANGED
@@ -46,10 +46,27 @@ module Moped
|
|
46
46
|
# @since 2.0.0
|
47
47
|
def execute(node)
|
48
48
|
node.process(operation) do |reply|
|
49
|
-
|
50
|
-
|
49
|
+
# Avoid LocalJumpError
|
50
|
+
ret = nil
|
51
|
+
if reply.unauthorized? && node.credentials.key?(@database)
|
52
|
+
node.connection do |conn|
|
53
|
+
username, password = node.credentials[@database]
|
54
|
+
if username && password
|
55
|
+
conn.login(operation.database, username, password)
|
56
|
+
ret = execute(node)
|
57
|
+
end
|
58
|
+
end
|
51
59
|
end
|
52
|
-
|
60
|
+
|
61
|
+
if ret.nil?
|
62
|
+
if operation.failure?(reply)
|
63
|
+
raise operation.failure_exception(reply)
|
64
|
+
end
|
65
|
+
|
66
|
+
ret = operation.results(reply)
|
67
|
+
end
|
68
|
+
|
69
|
+
ret
|
53
70
|
end
|
54
71
|
end
|
55
72
|
end
|
@@ -1,6 +1,5 @@
|
|
1
1
|
module Moped
|
2
2
|
module Protocol
|
3
|
-
|
4
3
|
# The base class for building all messages needed to implement the Mongo
|
5
4
|
# Wire Protocol. It provides a minimal DSL for defining typed fields for
|
6
5
|
# serialization and deserialization over the wire.
|
@@ -34,6 +33,9 @@ module Moped
|
|
34
33
|
# int32 :op_code
|
35
34
|
#
|
36
35
|
module Message
|
36
|
+
INT32_DECODE_STR = 'l<'
|
37
|
+
INT64_DECODE_ARRAY_STR = 'q<*'
|
38
|
+
INT64_DECODE_STR = 'q<'
|
37
39
|
|
38
40
|
# Default implementation for a message is to do nothing when receiving
|
39
41
|
# replies.
|
@@ -214,11 +216,11 @@ module Moped
|
|
214
216
|
end
|
215
217
|
|
216
218
|
def serialize_#{name}(buffer)
|
217
|
-
buffer << [#{name}_as_int].pack(
|
219
|
+
buffer << [#{name}_as_int].pack(INT32_DECODE_STR)
|
218
220
|
end
|
219
221
|
|
220
222
|
def deserialize_#{name}(buffer)
|
221
|
-
bits, = buffer.read(4).unpack(
|
223
|
+
bits, = buffer.read(4).unpack(INT32_DECODE_STR)
|
222
224
|
|
223
225
|
self.#{name} = bits
|
224
226
|
end
|
@@ -244,11 +246,11 @@ module Moped
|
|
244
246
|
end
|
245
247
|
|
246
248
|
def serialize_#{name}(buffer)
|
247
|
-
buffer << [#{name}].pack(
|
249
|
+
buffer << [#{name}].pack(INT32_DECODE_STR)
|
248
250
|
end
|
249
251
|
|
250
252
|
def deserialize_#{name}(buffer)
|
251
|
-
self.#{name}, = buffer.read(4).unpack(
|
253
|
+
self.#{name}, = buffer.read(4).unpack(INT32_DECODE_STR)
|
252
254
|
end
|
253
255
|
RUBY
|
254
256
|
|
@@ -280,7 +282,7 @@ module Moped
|
|
280
282
|
end
|
281
283
|
|
282
284
|
def serialize_#{name}(buffer)
|
283
|
-
buffer << #{name}.pack(
|
285
|
+
buffer << #{name}.pack(INT64_DECODE_ARRAY_STR)
|
284
286
|
end
|
285
287
|
|
286
288
|
def deserialize_#{name}(buffer)
|
@@ -294,11 +296,11 @@ module Moped
|
|
294
296
|
end
|
295
297
|
|
296
298
|
def serialize_#{name}(buffer)
|
297
|
-
buffer << [#{name}].pack(
|
299
|
+
buffer << [#{name}].pack(INT64_DECODE_STR)
|
298
300
|
end
|
299
301
|
|
300
302
|
def deserialize_#{name}(buffer)
|
301
|
-
self.#{name}, = buffer.read(8).unpack(
|
303
|
+
self.#{name}, = buffer.read(8).unpack(INT64_DECODE_STR)
|
302
304
|
end
|
303
305
|
RUBY
|
304
306
|
end
|
data/lib/moped/query.rb
CHANGED
@@ -21,6 +21,7 @@ module Moped
|
|
21
21
|
# people.find.count # => 1
|
22
22
|
class Query
|
23
23
|
include Enumerable
|
24
|
+
include Retryable
|
24
25
|
|
25
26
|
# @attribute [r] collection The collection to execute the query on.
|
26
27
|
# @attribute [r] operation The query operation.
|
@@ -321,14 +322,16 @@ module Moped
|
|
321
322
|
#
|
322
323
|
# @since 1.0.0
|
323
324
|
def remove
|
324
|
-
cluster
|
325
|
-
node
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
325
|
+
with_retry(cluster) do
|
326
|
+
cluster.with_primary do |node|
|
327
|
+
node.remove(
|
328
|
+
operation.database,
|
329
|
+
operation.collection,
|
330
|
+
operation.basic_selector,
|
331
|
+
write_concern,
|
332
|
+
flags: [ :remove_first ]
|
333
|
+
)
|
334
|
+
end
|
332
335
|
end
|
333
336
|
end
|
334
337
|
|
@@ -341,13 +344,15 @@ module Moped
|
|
341
344
|
#
|
342
345
|
# @since 1.0.0
|
343
346
|
def remove_all
|
344
|
-
cluster
|
345
|
-
node
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
347
|
+
with_retry(cluster) do
|
348
|
+
cluster.with_primary do |node|
|
349
|
+
node.remove(
|
350
|
+
operation.database,
|
351
|
+
operation.collection,
|
352
|
+
operation.basic_selector,
|
353
|
+
write_concern
|
354
|
+
)
|
355
|
+
end
|
351
356
|
end
|
352
357
|
end
|
353
358
|
|
@@ -423,15 +428,17 @@ module Moped
|
|
423
428
|
#
|
424
429
|
# @since 1.0.0
|
425
430
|
def update(change, flags = nil)
|
426
|
-
cluster
|
427
|
-
node
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
431
|
+
with_retry(cluster) do
|
432
|
+
cluster.with_primary do |node|
|
433
|
+
node.update(
|
434
|
+
operation.database,
|
435
|
+
operation.collection,
|
436
|
+
operation.selector["$query"] || operation.selector,
|
437
|
+
change,
|
438
|
+
write_concern,
|
439
|
+
flags: flags
|
440
|
+
)
|
441
|
+
end
|
435
442
|
end
|
436
443
|
end
|
437
444
|
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
+
require "moped/retryable"
|
2
3
|
module Moped
|
3
4
|
module ReadPreference
|
4
5
|
|
@@ -7,6 +8,7 @@ module Moped
|
|
7
8
|
#
|
8
9
|
# @since 2.0.0
|
9
10
|
module Selectable
|
11
|
+
include Retryable
|
10
12
|
|
11
13
|
# @!attribute tags
|
12
14
|
# @return [ Array<Hash> ] The tag sets.
|
@@ -39,41 +41,6 @@ module Moped
|
|
39
41
|
options[:flags] |= [ :slave_ok ]
|
40
42
|
options
|
41
43
|
end
|
42
|
-
|
43
|
-
private
|
44
|
-
|
45
|
-
# Execute the provided block on the cluster and retry if the execution
|
46
|
-
# fails.
|
47
|
-
#
|
48
|
-
# @api private
|
49
|
-
#
|
50
|
-
# @example Execute with retry.
|
51
|
-
# preference.with_retry(cluster) do
|
52
|
-
# cluster.with_primary do |node|
|
53
|
-
# node.refresh
|
54
|
-
# end
|
55
|
-
# end
|
56
|
-
#
|
57
|
-
# @param [ Cluster ] cluster The cluster.
|
58
|
-
# @param [ Integer ] retries The number of times to retry.
|
59
|
-
#
|
60
|
-
# @return [ Object ] The result of the block.
|
61
|
-
#
|
62
|
-
# @since 2.0.0
|
63
|
-
def with_retry(cluster, retries = cluster.max_retries, &block)
|
64
|
-
begin
|
65
|
-
block.call
|
66
|
-
rescue Errors::ConnectionFailure => e
|
67
|
-
if retries > 0
|
68
|
-
Loggable.warn(" MOPED:", "Retrying connection attempt #{retries} more time(s).", "n/a")
|
69
|
-
sleep(cluster.retry_interval)
|
70
|
-
cluster.refresh
|
71
|
-
with_retry(cluster, retries - 1, &block)
|
72
|
-
else
|
73
|
-
raise e
|
74
|
-
end
|
75
|
-
end
|
76
|
-
end
|
77
44
|
end
|
78
45
|
end
|
79
46
|
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Moped
|
3
|
+
# Provides the shared behaviour for retry failed operations.
|
4
|
+
#
|
5
|
+
# @since 2.0.0
|
6
|
+
module Retryable
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
# Execute the provided block on the cluster and retry if the execution
|
11
|
+
# fails.
|
12
|
+
#
|
13
|
+
# @api private
|
14
|
+
#
|
15
|
+
# @example Execute with retry.
|
16
|
+
# preference.with_retry(cluster) do
|
17
|
+
# cluster.with_primary do |node|
|
18
|
+
# node.refresh
|
19
|
+
# end
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# @param [ Cluster ] cluster The cluster.
|
23
|
+
# @param [ Integer ] retries The number of times to retry.
|
24
|
+
#
|
25
|
+
# @return [ Object ] The result of the block.
|
26
|
+
#
|
27
|
+
# @since 2.0.0
|
28
|
+
def with_retry(cluster, retries = cluster.max_retries, &block)
|
29
|
+
begin
|
30
|
+
block.call
|
31
|
+
rescue Errors::ConnectionFailure, Errors::PotentialReconfiguration => e
|
32
|
+
raise e if e.is_a?(Errors::PotentialReconfiguration) &&
|
33
|
+
! (e.message.include?("not master") || e.message.include?("Not primary"))
|
34
|
+
|
35
|
+
if retries > 0
|
36
|
+
Loggable.warn(" MOPED:", "Retrying connection attempt #{retries} more time(s), nodes is #{cluster.nodes.inspect}, seeds are #{cluster.seeds.inspect}, cluster is #{cluster.inspect}. Error backtrace is #{e.backtrace}.", "n/a")
|
37
|
+
sleep(cluster.retry_interval)
|
38
|
+
cluster.refresh
|
39
|
+
with_retry(cluster, retries - 1, &block)
|
40
|
+
else
|
41
|
+
raise e
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/lib/moped/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: moped
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Durran Jordan
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2015-
|
12
|
+
date: 2015-08-15 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bson
|
@@ -17,14 +17,14 @@ dependencies:
|
|
17
17
|
requirements:
|
18
18
|
- - "~>"
|
19
19
|
- !ruby/object:Gem::Version
|
20
|
-
version: '
|
20
|
+
version: '3.0'
|
21
21
|
type: :runtime
|
22
22
|
prerelease: false
|
23
23
|
version_requirements: !ruby/object:Gem::Requirement
|
24
24
|
requirements:
|
25
25
|
- - "~>"
|
26
26
|
- !ruby/object:Gem::Version
|
27
|
-
version: '
|
27
|
+
version: '3.0'
|
28
28
|
- !ruby/object:Gem::Dependency
|
29
29
|
name: connection_pool
|
30
30
|
requirement: !ruby/object:Gem::Requirement
|
@@ -114,6 +114,7 @@ files:
|
|
114
114
|
- lib/moped/read_preference/secondary_preferred.rb
|
115
115
|
- lib/moped/read_preference/selectable.rb
|
116
116
|
- lib/moped/readable.rb
|
117
|
+
- lib/moped/retryable.rb
|
117
118
|
- lib/moped/session.rb
|
118
119
|
- lib/moped/uri.rb
|
119
120
|
- lib/moped/version.rb
|