moped 1.2.6 → 1.2.7

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of moped might be problematic. Click here for more details.

@@ -1,5 +1,26 @@
1
1
  # Overview
2
2
 
3
+ ## 1.2.7
4
+
5
+ ### Resolved Issues
6
+
7
+ * \#87 `Moped::BSON::ObjectId.legal?` now returns true for object ids.
8
+
9
+ * \#85 Allow `===` comparisons with object ids to check for equality of the
10
+ underlying string. (Bob Aman)
11
+
12
+ * \#84 Query hints are no longer wiped on explain.
13
+
14
+ * \#60/\#80 Moped now gracefully handles replica set reconfig and crashes of the
15
+ primary and secondary. By default, the node list will be refreshed every
16
+ second and the operation will be retried up to 30 times. This is configurable
17
+ by setting the `:max_retries` and `:retry_interval` options on the session.
18
+
19
+ Moped::Session.new(
20
+ [ "node1:27017", "node2:27017" ],
21
+ retry_interval: 0.5, max_retries: 45
22
+ )
23
+
3
24
  ## 1.2.6
4
25
 
5
26
  ### Resolved Issues
@@ -17,7 +17,7 @@ module Moped
17
17
  end
18
18
 
19
19
  def legal?(str)
20
- /\A\h{24}\Z/ === str
20
+ /\A\h{24}\Z/ === str.to_s
21
21
  end
22
22
 
23
23
  def from_data(data)
@@ -27,6 +27,11 @@ module Moped
27
27
  end
28
28
  end
29
29
 
30
+ def ===(other)
31
+ return to_str === other.to_str if other.respond_to?(:to_str)
32
+ super
33
+ end
34
+
30
35
  def data
31
36
  # If @data is defined, then we know we've been loaded in some
32
37
  # non-standard way, so we attempt to repair the data.
@@ -51,6 +56,7 @@ module Moped
51
56
  def to_s
52
57
  data.unpack("H*")[0]
53
58
  end
59
+ alias :to_str :to_s
54
60
 
55
61
  def inspect
56
62
  to_s.inspect
@@ -4,8 +4,9 @@ module Moped
4
4
  # node, a replica set, or a mongos server.
5
5
  class Cluster
6
6
 
7
+ # @attribute [r] options The cluster options.
7
8
  # @attribute [r] seeds The seeds the cluster was initialized with.
8
- attr_reader :seeds
9
+ attr_reader :options, :seeds
9
10
 
10
11
  # Get the authentication details for the cluster.
11
12
  #
@@ -30,6 +31,57 @@ module Moped
30
31
  nodes.each { |node| node.disconnect } and true
31
32
  end
32
33
 
34
+ # Get the interval at which a node should be flagged as down before
35
+ # retrying.
36
+ #
37
+ # @example Get the down interval, in seconds.
38
+ # cluster.down_interval
39
+ #
40
+ # @return [ Integer ] The down interval.
41
+ #
42
+ # @since 1.2.7
43
+ def down_interval
44
+ options[:down_interval]
45
+ end
46
+
47
+ # Get the number of times an operation should be retried before raising an
48
+ # error.
49
+ #
50
+ # @example Get the maximum retries.
51
+ # cluster.max_retries
52
+ #
53
+ # @return [ Integer ] The max retries.
54
+ #
55
+ # @since 1.2.7
56
+ def max_retries
57
+ options[:max_retries]
58
+ end
59
+
60
+ # Get the interval in which the node list should be refreshed.
61
+ #
62
+ # @example Get the refresh interval, in seconds.
63
+ # cluster.refresh_interval
64
+ #
65
+ # @return [ Integer ] The refresh interval.
66
+ #
67
+ # @since 1.2.7
68
+ def refresh_interval
69
+ options[:refresh_interval]
70
+ end
71
+
72
+ # Get the operation retry interval - the time to wait before retrying a
73
+ # single operation.
74
+ #
75
+ # @example Get the retry interval, in seconds.
76
+ # cluster.retry_interval
77
+ #
78
+ # @return [ Integer ] The retry interval.
79
+ #
80
+ # @since 1.2.7
81
+ def retry_interval
82
+ options[:retry_interval]
83
+ end
84
+
33
85
  # Initialize the new cluster.
34
86
  #
35
87
  # @example Initialize the cluster.
@@ -46,7 +98,9 @@ module Moped
46
98
  def initialize(hosts, options)
47
99
  @options = {
48
100
  down_interval: 30,
49
- refresh_interval: 300
101
+ max_retries: 30,
102
+ refresh_interval: 300,
103
+ retry_interval: 1
50
104
  }.merge(options)
51
105
 
52
106
  @seeds = hosts
@@ -65,8 +119,8 @@ module Moped
65
119
  # @since 1.0.0
66
120
  def nodes
67
121
  current_time = Time.new
68
- down_boundary = current_time - @options[:down_interval]
69
- refresh_boundary = current_time - @options[:refresh_interval]
122
+ down_boundary = current_time - down_interval
123
+ refresh_boundary = current_time - refresh_interval
70
124
 
71
125
  # Find the nodes that were down but are ready to be refreshed, or those
72
126
  # with stale connection information.
@@ -135,15 +189,14 @@ module Moped
135
189
  # # ...
136
190
  # end
137
191
  #
138
- # @param [ true, false ] retry_on_failure Whether to retry if an error was
139
- # raised.
192
+ # @param [ Integer ] retries The number of times to retry.
140
193
  #
141
194
  # @raises [ ConnectionFailure ] When no primary node can be found
142
195
  #
143
196
  # @return [ Object ] The result of the yield.
144
197
  #
145
198
  # @since 1.0.0
146
- def with_primary(retry_on_failure = true, &block)
199
+ def with_primary(retries = max_retries, &block)
147
200
  if node = nodes.find(&:primary?)
148
201
  begin
149
202
  node.ensure_primary do
@@ -155,10 +208,11 @@ module Moped
155
208
  end
156
209
  end
157
210
 
158
- if retry_on_failure
211
+ if retries > 0
159
212
  # We couldn't find a primary node, so refresh the list and try again.
213
+ sleep(retry_interval)
160
214
  refresh
161
- with_primary(false, &block)
215
+ with_primary(retries - 1, &block)
162
216
  else
163
217
  raise(
164
218
  Errors::ConnectionFailure,
@@ -175,15 +229,14 @@ module Moped
175
229
  # # ...
176
230
  # end
177
231
  #
178
- # @param [ true, false ] retry_on_failure Whether to retry if an error was
179
- # raised.
232
+ # @param [ Integer ] retries The number of times to retry.
180
233
  #
181
234
  # @raises [ ConnectionFailure ] When no primary node can be found
182
235
  #
183
236
  # @return [ Object ] The result of the yield.
184
237
  #
185
238
  # @since 1.0.0
186
- def with_secondary(retry_on_failure = true, &block)
239
+ def with_secondary(retries = max_retries, &block)
187
240
  available_nodes = nodes.shuffle!.partition(&:secondary?).flatten
188
241
 
189
242
  while node = available_nodes.shift
@@ -195,11 +248,12 @@ module Moped
195
248
  end
196
249
  end
197
250
 
198
- if retry_on_failure
251
+ if retries > 0
199
252
  # We couldn't find a secondary or primary node, so refresh the list and
200
253
  # try again.
254
+ sleep(retry_interval)
201
255
  refresh
202
- with_secondary(false, &block)
256
+ with_secondary(retries - 1, &block)
203
257
  else
204
258
  raise(
205
259
  Errors::ConnectionFailure,
@@ -235,7 +235,7 @@ module Moped
235
235
  yield
236
236
  rescue Timeout::Error
237
237
  raise Errors::ConnectionFailure, "Timed out connection to Mongo on #{host}:#{port}"
238
- rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH
238
+ rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH, Errno::EPIPE
239
239
  raise Errors::ConnectionFailure, "Could not connect to Mongo on #{host}:#{port}"
240
240
  rescue Errno::ECONNRESET
241
241
  raise Errors::ConnectionFailure, "Connection reset to Mongo on #{host}:#{port}"
@@ -89,12 +89,15 @@ module Moped
89
89
  #
90
90
  # @since 1.0.0
91
91
  def explain
92
+ hint, sort = operation.selector["$hint"], operation.selector["$orderby"]
92
93
  operation.selector = {
93
94
  "$query" => selector,
94
- "$orderby" => operation.selector.fetch("$orderby", {}),
95
95
  "$explain" => true,
96
96
  "$limit" => operation.selector.fetch("$limit", 1).abs * -1
97
- } and each { |doc| return doc }
97
+ }
98
+ operation.selector["$orderby"] = sort if sort
99
+ operation.selector["$hint"] = hint if hint
100
+ each { |doc| return doc }
98
101
  end
99
102
 
100
103
  # Get the first matching document.
@@ -177,6 +177,10 @@ module Moped
177
177
  # specified safety level e.g., "fsync: true", or "w: 2, wtimeout: 5".
178
178
  # @option options [ Symbol, String ] :database The database to use.
179
179
  # @option options [ :strong, :eventual ] :consistency (:eventual).
180
+ # @option options [ Integer ] :max_retries The maximum number of attempts
181
+ # to retry an operation. (30)
182
+ # @option options [ Integer ] :retry_interval The time in seconds to retry
183
+ # connections to a secondary or primary after a failure. (1)
180
184
  #
181
185
  # @since 1.0.0
182
186
  def initialize(seeds, options = {})
@@ -1,4 +1,4 @@
1
1
  # encoding: utf-8
2
2
  module Moped
3
- VERSION = "1.2.6"
3
+ VERSION = "1.2.7"
4
4
  end
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: 1.2.6
4
+ version: 1.2.7
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-10-04 00:00:00.000000000 Z
12
+ date: 2012-10-06 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: A MongoDB driver for Ruby.
15
15
  email:
@@ -85,7 +85,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
85
85
  version: '0'
86
86
  segments:
87
87
  - 0
88
- hash: 452106332214392784
88
+ hash: -1523010636318133543
89
89
  required_rubygems_version: !ruby/object:Gem::Requirement
90
90
  none: false
91
91
  requirements:
@@ -94,7 +94,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
94
94
  version: '0'
95
95
  segments:
96
96
  - 0
97
- hash: 452106332214392784
97
+ hash: -1523010636318133543
98
98
  requirements: []
99
99
  rubyforge_project:
100
100
  rubygems_version: 1.8.24