moped 1.5.3 → 2.0.0.beta
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.
Potentially problematic release.
This version of moped might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +42 -5
- data/README.md +1 -1
- data/lib/moped.rb +10 -13
- data/lib/moped/address.rb +56 -0
- data/lib/moped/authenticatable.rb +89 -0
- data/lib/moped/cluster.rb +169 -136
- data/lib/moped/collection.rb +53 -19
- data/lib/moped/connection.rb +69 -10
- data/lib/moped/connection/manager.rb +49 -0
- data/lib/moped/connection/pool.rb +198 -0
- data/lib/moped/connection/queue.rb +93 -0
- data/lib/moped/connection/reaper.rb +52 -0
- data/lib/moped/connection/socket.rb +4 -0
- data/lib/moped/connection/socket/connectable.rb +169 -0
- data/lib/moped/connection/socket/ssl.rb +52 -0
- data/lib/moped/connection/socket/tcp.rb +25 -0
- data/lib/moped/connection/sockets.rb +4 -0
- data/lib/moped/cursor.rb +3 -5
- data/lib/moped/database.rb +18 -24
- data/lib/moped/errors.rb +35 -6
- data/lib/moped/executable.rb +96 -0
- data/lib/moped/failover.rb +41 -0
- data/lib/moped/failover/disconnect.rb +31 -0
- data/lib/moped/failover/ignore.rb +29 -0
- data/lib/moped/failover/reconfigure.rb +34 -0
- data/lib/moped/failover/retry.rb +37 -0
- data/lib/moped/indexes.rb +4 -1
- data/lib/moped/instrumentable.rb +39 -0
- data/lib/moped/instrumentable/log.rb +43 -0
- data/lib/moped/instrumentable/noop.rb +31 -0
- data/lib/moped/loggable.rb +110 -0
- data/lib/moped/node.rb +316 -297
- data/lib/moped/operation.rb +3 -0
- data/lib/moped/operation/read.rb +62 -0
- data/lib/moped/operation/write.rb +57 -0
- data/lib/moped/protocol/command.rb +65 -4
- data/lib/moped/protocol/commands/authenticate.rb +1 -2
- data/lib/moped/protocol/delete.rb +16 -0
- data/lib/moped/protocol/get_more.rb +102 -31
- data/lib/moped/protocol/insert.rb +17 -0
- data/lib/moped/protocol/message.rb +44 -46
- data/lib/moped/protocol/query.rb +175 -92
- data/lib/moped/protocol/reply.rb +19 -8
- data/lib/moped/protocol/update.rb +18 -0
- data/lib/moped/query.rb +43 -17
- data/lib/moped/read_preference.rb +49 -0
- data/lib/moped/read_preference/nearest.rb +55 -0
- data/lib/moped/read_preference/primary.rb +60 -0
- data/lib/moped/read_preference/primary_preferred.rb +55 -0
- data/lib/moped/read_preference/secondary.rb +50 -0
- data/lib/moped/read_preference/secondary_preferred.rb +53 -0
- data/lib/moped/read_preference/selectable.rb +79 -0
- data/lib/moped/readable.rb +55 -0
- data/lib/moped/session.rb +122 -70
- data/lib/moped/{mongo_uri.rb → uri.rb} +75 -31
- data/lib/moped/version.rb +1 -1
- data/lib/moped/write_concern.rb +33 -0
- data/lib/moped/write_concern/propagate.rb +38 -0
- data/lib/moped/write_concern/unverified.rb +28 -0
- metadata +79 -44
- data/lib/moped/bson.rb +0 -45
- data/lib/moped/bson/binary.rb +0 -137
- data/lib/moped/bson/code.rb +0 -112
- data/lib/moped/bson/document.rb +0 -41
- data/lib/moped/bson/extensions.rb +0 -91
- data/lib/moped/bson/extensions/array.rb +0 -37
- data/lib/moped/bson/extensions/boolean.rb +0 -16
- data/lib/moped/bson/extensions/false_class.rb +0 -19
- data/lib/moped/bson/extensions/float.rb +0 -22
- data/lib/moped/bson/extensions/hash.rb +0 -39
- data/lib/moped/bson/extensions/integer.rb +0 -36
- data/lib/moped/bson/extensions/nil_class.rb +0 -19
- data/lib/moped/bson/extensions/object.rb +0 -11
- data/lib/moped/bson/extensions/regexp.rb +0 -38
- data/lib/moped/bson/extensions/string.rb +0 -45
- data/lib/moped/bson/extensions/symbol.rb +0 -33
- data/lib/moped/bson/extensions/time.rb +0 -23
- data/lib/moped/bson/extensions/true_class.rb +0 -19
- data/lib/moped/bson/max_key.rb +0 -51
- data/lib/moped/bson/min_key.rb +0 -51
- data/lib/moped/bson/object_id.rb +0 -301
- data/lib/moped/bson/timestamp.rb +0 -38
- data/lib/moped/bson/types.rb +0 -67
- data/lib/moped/logging.rb +0 -58
- data/lib/moped/session/context.rb +0 -115
- data/lib/moped/sockets/connectable.rb +0 -167
- data/lib/moped/sockets/ssl.rb +0 -50
- data/lib/moped/sockets/tcp.rb +0 -23
- data/lib/moped/threaded.rb +0 -69
data/lib/moped/protocol/reply.rb
CHANGED
@@ -67,8 +67,8 @@ module Moped
|
|
67
67
|
#
|
68
68
|
# @since 1.2.10
|
69
69
|
def command_failure?
|
70
|
-
result = documents
|
71
|
-
result["ok"] != 1
|
70
|
+
result = documents.first
|
71
|
+
(result["ok"] != 1.0 && result["ok"] != true) || error?
|
72
72
|
end
|
73
73
|
|
74
74
|
# Was the provided cursor id not found on the server?
|
@@ -83,17 +83,29 @@ module Moped
|
|
83
83
|
flags.include?(:cursor_not_found)
|
84
84
|
end
|
85
85
|
|
86
|
+
# Check if the first returned document in the reply is an error result.
|
87
|
+
#
|
88
|
+
# @example Is the first document in the reply an error?
|
89
|
+
# reply.error?
|
90
|
+
#
|
91
|
+
# @return [ true, false ] If the first document is an error.
|
92
|
+
#
|
93
|
+
# @since 2.0.0
|
94
|
+
def error?
|
95
|
+
result = documents.first
|
96
|
+
result && error_message(result)
|
97
|
+
end
|
98
|
+
|
86
99
|
# Did the query fail on the server?
|
87
100
|
#
|
88
101
|
# @example Did the query fail?
|
89
|
-
# reply.
|
102
|
+
# reply.query_failure?
|
90
103
|
#
|
91
104
|
# @return [ true, false ] If the query failed.
|
92
105
|
#
|
93
106
|
# @since 1.2.0
|
94
|
-
def
|
95
|
-
|
96
|
-
flags.include?(:query_failure) || (result && (result["err"] || result["errmsg"] || result["$err"]))
|
107
|
+
def query_failure?
|
108
|
+
flags.include?(:query_failure) || error?
|
97
109
|
end
|
98
110
|
|
99
111
|
# Is the reply an error message that we are not authorized for the query
|
@@ -144,7 +156,7 @@ module Moped
|
|
144
156
|
def deserialize_documents(buffer)
|
145
157
|
documents = []
|
146
158
|
count.times do
|
147
|
-
documents << BSON::Document.
|
159
|
+
documents << BSON::Document.from_bson(buffer)
|
148
160
|
end
|
149
161
|
@documents = documents
|
150
162
|
end
|
@@ -152,7 +164,6 @@ module Moped
|
|
152
164
|
def error_message(result)
|
153
165
|
result["err"] || result["errmsg"] || result["$err"]
|
154
166
|
end
|
155
|
-
|
156
167
|
end
|
157
168
|
end
|
158
169
|
end
|
@@ -105,6 +105,24 @@ module Moped
|
|
105
105
|
update.inspect,
|
106
106
|
flags.inspect]
|
107
107
|
end
|
108
|
+
|
109
|
+
private
|
110
|
+
|
111
|
+
# Duplicate the attributes in the update that need to be.
|
112
|
+
#
|
113
|
+
# @api private
|
114
|
+
#
|
115
|
+
# @example Clone the update.
|
116
|
+
# update.clone
|
117
|
+
#
|
118
|
+
# @param [ Update ] The update that was cloned from.
|
119
|
+
#
|
120
|
+
# @since 2.0.0
|
121
|
+
def initialize_copy(_)
|
122
|
+
@selector = selector.dup
|
123
|
+
@update = update.dup
|
124
|
+
@flags = flags.dup
|
125
|
+
end
|
108
126
|
end
|
109
127
|
end
|
110
128
|
end
|
data/lib/moped/query.rb
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "moped/cursor"
|
3
|
+
|
1
4
|
module Moped
|
2
5
|
|
3
6
|
# The +Query+ class encapsulates all of the logic related to building
|
@@ -112,15 +115,19 @@ module Moped
|
|
112
115
|
#
|
113
116
|
# @since 1.0.0
|
114
117
|
def first
|
115
|
-
reply =
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
118
|
+
reply = read_preference.with_node(cluster) do |node|
|
119
|
+
node.query(
|
120
|
+
operation.database,
|
121
|
+
operation.collection,
|
122
|
+
operation.selector,
|
123
|
+
query_options(
|
124
|
+
fields: operation.fields,
|
125
|
+
flags: operation.flags,
|
126
|
+
skip: operation.skip,
|
127
|
+
limit: -1
|
128
|
+
)
|
129
|
+
)
|
130
|
+
end
|
124
131
|
reply.documents.first
|
125
132
|
end
|
126
133
|
alias :one :first
|
@@ -252,7 +259,7 @@ module Moped
|
|
252
259
|
command[:fields] = operation.fields if operation.fields
|
253
260
|
command[:update] = change unless options[:remove]
|
254
261
|
|
255
|
-
result = session.with(
|
262
|
+
result = session.with(read: :primary) do |sess|
|
256
263
|
sess.command(command)["value"]
|
257
264
|
end
|
258
265
|
|
@@ -269,11 +276,12 @@ module Moped
|
|
269
276
|
#
|
270
277
|
# @since 1.0.0
|
271
278
|
def remove
|
272
|
-
|
273
|
-
|
279
|
+
cluster.with_primary do |node|
|
280
|
+
node.remove(
|
274
281
|
operation.database,
|
275
282
|
operation.collection,
|
276
283
|
operation.basic_selector,
|
284
|
+
write_concern,
|
277
285
|
flags: [ :remove_first ]
|
278
286
|
)
|
279
287
|
end
|
@@ -288,11 +296,12 @@ module Moped
|
|
288
296
|
#
|
289
297
|
# @since 1.0.0
|
290
298
|
def remove_all
|
291
|
-
|
292
|
-
|
299
|
+
cluster.with_primary do |node|
|
300
|
+
node.remove(
|
293
301
|
operation.database,
|
294
302
|
operation.collection,
|
295
|
-
operation.basic_selector
|
303
|
+
operation.basic_selector,
|
304
|
+
write_concern
|
296
305
|
)
|
297
306
|
end
|
298
307
|
end
|
@@ -369,12 +378,13 @@ module Moped
|
|
369
378
|
#
|
370
379
|
# @since 1.0.0
|
371
380
|
def update(change, flags = nil)
|
372
|
-
|
373
|
-
|
381
|
+
cluster.with_primary do |node|
|
382
|
+
node.update(
|
374
383
|
operation.database,
|
375
384
|
operation.collection,
|
376
385
|
operation.selector["$query"] || operation.selector,
|
377
386
|
change,
|
387
|
+
write_concern,
|
378
388
|
flags: flags
|
379
389
|
)
|
380
390
|
end
|
@@ -412,6 +422,22 @@ module Moped
|
|
412
422
|
update(change, [ :upsert ])
|
413
423
|
end
|
414
424
|
|
425
|
+
def write_concern
|
426
|
+
session.write_concern
|
427
|
+
end
|
428
|
+
|
429
|
+
def read_preference
|
430
|
+
session.read_preference
|
431
|
+
end
|
432
|
+
|
433
|
+
def cluster
|
434
|
+
session.cluster
|
435
|
+
end
|
436
|
+
|
437
|
+
def query_options(options)
|
438
|
+
read_preference.query_options(options)
|
439
|
+
end
|
440
|
+
|
415
441
|
private
|
416
442
|
|
417
443
|
def initialize_copy(other)
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "moped/read_preference/selectable"
|
3
|
+
require "moped/read_preference/nearest"
|
4
|
+
require "moped/read_preference/primary"
|
5
|
+
require "moped/read_preference/primary_preferred"
|
6
|
+
require "moped/read_preference/secondary"
|
7
|
+
require "moped/read_preference/secondary_preferred"
|
8
|
+
|
9
|
+
module Moped
|
10
|
+
|
11
|
+
# Provides behaviour around getting various read preference implementations.
|
12
|
+
#
|
13
|
+
# @since 2.0.0
|
14
|
+
module ReadPreference
|
15
|
+
extend self
|
16
|
+
|
17
|
+
# Hash lookup for the read preference classes based off the symbols
|
18
|
+
# provided in configuration.
|
19
|
+
#
|
20
|
+
# @since 2.0.0
|
21
|
+
PREFERENCES = {
|
22
|
+
nearest: Nearest,
|
23
|
+
primary: Primary,
|
24
|
+
primary_preferred: PrimaryPreferred,
|
25
|
+
secondary: Secondary,
|
26
|
+
secondary_preferred: SecondaryPreferred
|
27
|
+
}.freeze
|
28
|
+
|
29
|
+
# Get a read preference for the provided name. Valid names are:
|
30
|
+
# - :nearest
|
31
|
+
# - :primary
|
32
|
+
# - :primary_preferred
|
33
|
+
# - :secondary
|
34
|
+
# - :secondary_preferred
|
35
|
+
#
|
36
|
+
# @example Get the primary read preference.
|
37
|
+
# Moped::ReadPreference.get(:primary)
|
38
|
+
#
|
39
|
+
# @param [ Symbol ] name The name of the preference.
|
40
|
+
# @param [ Array<Hash> ] tags The tag sets to match the node on.
|
41
|
+
#
|
42
|
+
# @return [ Object ] The appropriate read preference.
|
43
|
+
#
|
44
|
+
# @since 2.0.0
|
45
|
+
def get(name, tags = nil)
|
46
|
+
PREFERENCES.fetch(name.to_sym).new(tags)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Moped
|
3
|
+
module ReadPreference
|
4
|
+
|
5
|
+
# Encapsulates behaviour around a nearest read preference.
|
6
|
+
#
|
7
|
+
# @since 2.0.0
|
8
|
+
class Nearest
|
9
|
+
include Selectable
|
10
|
+
|
11
|
+
# Get the name for the read preference on the server side.
|
12
|
+
#
|
13
|
+
# @example Get the name of the read preference.
|
14
|
+
# nearest.name
|
15
|
+
#
|
16
|
+
# @return [ Symbol ] :nearest.
|
17
|
+
#
|
18
|
+
# @since 2.0.0
|
19
|
+
def name
|
20
|
+
:nearest
|
21
|
+
end
|
22
|
+
|
23
|
+
# Execute the provided block on the node with the lowest latency,
|
24
|
+
# allowing either primary or secondary.
|
25
|
+
#
|
26
|
+
# @example Read from the nearest node in the cluster.
|
27
|
+
# preference.with_node(cluster) do |node|
|
28
|
+
# node.command(ismaster: 1)
|
29
|
+
# end
|
30
|
+
#
|
31
|
+
# @note If tag sets are provided then selection will need to
|
32
|
+
# match the provided tags.
|
33
|
+
#
|
34
|
+
# @param [ Cluster ] cluster The cluster of nodes to select from.
|
35
|
+
# @param [ Proc ] block The block to execute on the node.
|
36
|
+
#
|
37
|
+
# @raise [ Errors::ConnectionFailure ] If no node was available in the
|
38
|
+
# cluster.
|
39
|
+
#
|
40
|
+
# @return [ Object ] The result of the block.
|
41
|
+
#
|
42
|
+
# @since 2.0.0
|
43
|
+
def with_node(cluster, &block)
|
44
|
+
with_retry(cluster) do
|
45
|
+
nearest = cluster.nodes.sort_by(&:latency).first
|
46
|
+
if nearest
|
47
|
+
block.call(nearest)
|
48
|
+
else
|
49
|
+
raise Errors::ConnectionFailure, "No nodes available to select in the cluster"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Moped
|
3
|
+
module ReadPreference
|
4
|
+
|
5
|
+
# Encapsulates behaviour around a primary read preference.
|
6
|
+
#
|
7
|
+
# @since 2.0.0
|
8
|
+
class Primary
|
9
|
+
include Selectable
|
10
|
+
|
11
|
+
# Get the name for the read preference on the server side.
|
12
|
+
#
|
13
|
+
# @example Get the name of the read preference.
|
14
|
+
# primary.name
|
15
|
+
#
|
16
|
+
# @return [ Symbol ] :primary.
|
17
|
+
#
|
18
|
+
# @since 2.0.0
|
19
|
+
def name
|
20
|
+
:primary
|
21
|
+
end
|
22
|
+
|
23
|
+
# Get the provided options as query options for this read preference.
|
24
|
+
#
|
25
|
+
# @example Get the query options.
|
26
|
+
# preference.query_options({})
|
27
|
+
#
|
28
|
+
# @param [ Hash ] options The existing options for the query.
|
29
|
+
#
|
30
|
+
# @return [ Hash ] The options plus additional query options.
|
31
|
+
#
|
32
|
+
# @since 2.0.0
|
33
|
+
def query_options(options)
|
34
|
+
options
|
35
|
+
end
|
36
|
+
|
37
|
+
# Select a primary node from the cluster. If no primary node is available
|
38
|
+
# then an exception will be raised.
|
39
|
+
#
|
40
|
+
# @example Select a primary node from the cluster.
|
41
|
+
# preference.with_node(cluster) do |node|
|
42
|
+
# node.command(ismaster: 1)
|
43
|
+
# end
|
44
|
+
#
|
45
|
+
# @param [ Cluster ] cluster The cluster of nodes to select from.
|
46
|
+
# @param [ Proc ] block The block to execute on the node.
|
47
|
+
#
|
48
|
+
# @raise [ Errors::ConnectionFailure ] If no primary node was available in the cluster.
|
49
|
+
#
|
50
|
+
# @return [ Object ] The result of the block.
|
51
|
+
#
|
52
|
+
# @since 2.0.0
|
53
|
+
def with_node(cluster, &block)
|
54
|
+
with_retry(cluster) do
|
55
|
+
cluster.with_primary(&block)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Moped
|
3
|
+
module ReadPreference
|
4
|
+
|
5
|
+
# Encapsulates behaviour around a primary preferred read preference.
|
6
|
+
#
|
7
|
+
# @since 2.0.0
|
8
|
+
class PrimaryPreferred
|
9
|
+
include Selectable
|
10
|
+
|
11
|
+
# Get the name for the read preference on the server side.
|
12
|
+
#
|
13
|
+
# @example Get the name of the read preference.
|
14
|
+
# primary_preferred.name
|
15
|
+
#
|
16
|
+
# @return [ Symbol ] :primaryPreferred.
|
17
|
+
#
|
18
|
+
# @since 2.0.0
|
19
|
+
def name
|
20
|
+
:primaryPreferred
|
21
|
+
end
|
22
|
+
|
23
|
+
# Select a primary node from the cluster. If no primary node is available
|
24
|
+
# then attempt to select a secondary. If no secondary is available then
|
25
|
+
# an exception will be raised.
|
26
|
+
#
|
27
|
+
# @example Prefer to with_node a primary node from the cluster.
|
28
|
+
# preference.with_node(cluster) do |node|
|
29
|
+
# node.command(ismaster: 1)
|
30
|
+
# end
|
31
|
+
#
|
32
|
+
# @note If tag sets are provided then secondary with_nodeion will need to
|
33
|
+
# match the provided tags.
|
34
|
+
#
|
35
|
+
# @param [ Cluster ] cluster The cluster of nodes to select from.
|
36
|
+
# @param [ Proc ] block The block to execute on the node.
|
37
|
+
#
|
38
|
+
# @raise [ Errors::ConnectionFailure ] If no primary or secondary node was
|
39
|
+
# available in the cluster.
|
40
|
+
#
|
41
|
+
# @return [ Object ] The result of the block.
|
42
|
+
#
|
43
|
+
# @since 2.0.0
|
44
|
+
def with_node(cluster, &block)
|
45
|
+
with_retry(cluster) do
|
46
|
+
begin
|
47
|
+
cluster.with_primary(&block)
|
48
|
+
rescue Errors::ConnectionFailure
|
49
|
+
cluster.with_secondary(&block)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Moped
|
3
|
+
module ReadPreference
|
4
|
+
|
5
|
+
# Encapsulates behaviour around a secondary read preference.
|
6
|
+
#
|
7
|
+
# @since 2.0.0
|
8
|
+
class Secondary
|
9
|
+
include Selectable
|
10
|
+
|
11
|
+
# Get the name for the read preference on the server side.
|
12
|
+
#
|
13
|
+
# @example Get the name of the read preference.
|
14
|
+
# secondary.name
|
15
|
+
#
|
16
|
+
# @return [ Symbol ] :secondary.
|
17
|
+
#
|
18
|
+
# @since 2.0.0
|
19
|
+
def name
|
20
|
+
:secondary
|
21
|
+
end
|
22
|
+
|
23
|
+
# Select a secondary node from the cluster. If no secondary is available then
|
24
|
+
# an exception will be raised.
|
25
|
+
#
|
26
|
+
# @example Read from a secondary node from the cluster.
|
27
|
+
# preference.with_node(cluster) do |node|
|
28
|
+
# node.command(ismaster: 1)
|
29
|
+
# end
|
30
|
+
#
|
31
|
+
# @note If tag sets are provided then secondary selection will need to
|
32
|
+
# match the provided tags.
|
33
|
+
#
|
34
|
+
# @param [ Cluster ] cluster The cluster of nodes to select from.
|
35
|
+
# @param [ Proc ] block The block to execute on the node.
|
36
|
+
#
|
37
|
+
# @raise [ Errors::ConnectionFailure ] If no secondary node was available
|
38
|
+
# in the cluster.
|
39
|
+
#
|
40
|
+
# @return [ Object ] The result of the block.
|
41
|
+
#
|
42
|
+
# @since 2.0.0
|
43
|
+
def with_node(cluster, &block)
|
44
|
+
with_retry(cluster) do
|
45
|
+
cluster.with_secondary(&block)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|