moped 1.0.0.rc → 1.0.0
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.
- data/CHANGELOG.md +11 -0
- data/README.md +32 -467
- data/lib/moped.rb +0 -1
- data/lib/moped/bson.rb +3 -0
- data/lib/moped/bson/binary.rb +4 -4
- data/lib/moped/bson/code.rb +12 -10
- data/lib/moped/bson/extensions.rb +64 -54
- data/lib/moped/bson/extensions/array.rb +9 -6
- data/lib/moped/bson/extensions/boolean.rb +1 -1
- data/lib/moped/bson/extensions/false_class.rb +5 -2
- data/lib/moped/bson/extensions/float.rb +1 -2
- data/lib/moped/bson/extensions/hash.rb +4 -5
- data/lib/moped/bson/extensions/integer.rb +2 -4
- data/lib/moped/bson/extensions/nil_class.rb +1 -2
- data/lib/moped/bson/extensions/object.rb +13 -0
- data/lib/moped/bson/extensions/regexp.rb +5 -6
- data/lib/moped/bson/extensions/string.rb +24 -13
- data/lib/moped/bson/extensions/symbol.rb +12 -14
- data/lib/moped/bson/extensions/time.rb +4 -4
- data/lib/moped/bson/extensions/true_class.rb +5 -2
- data/lib/moped/bson/max_key.rb +1 -2
- data/lib/moped/bson/min_key.rb +1 -2
- data/lib/moped/bson/object_id.rb +44 -4
- data/lib/moped/bson/types.rb +1 -1
- data/lib/moped/cluster.rb +13 -5
- data/lib/moped/collection.rb +5 -1
- data/lib/moped/connection.rb +4 -4
- data/lib/moped/database.rb +58 -29
- data/lib/moped/logging.rb +3 -3
- data/lib/moped/node.rb +35 -6
- data/lib/moped/protocol/command.rb +1 -4
- data/lib/moped/protocol/delete.rb +2 -0
- data/lib/moped/protocol/get_more.rb +16 -1
- data/lib/moped/protocol/insert.rb +2 -0
- data/lib/moped/protocol/kill_cursors.rb +2 -0
- data/lib/moped/protocol/message.rb +31 -12
- data/lib/moped/protocol/query.rb +15 -3
- data/lib/moped/protocol/reply.rb +6 -4
- data/lib/moped/protocol/update.rb +2 -0
- data/lib/moped/query.rb +60 -5
- data/lib/moped/session.rb +53 -17
- data/lib/moped/session/context.rb +17 -7
- data/lib/moped/threaded.rb +2 -1
- data/lib/moped/version.rb +1 -1
- metadata +11 -6
data/CHANGELOG.md
ADDED
data/README.md
CHANGED
@@ -4,483 +4,48 @@ Moped [![Build Status](https://secure.travis-ci.org/mongoid/moped.png?branch=mas
|
|
4
4
|
Moped is a MongoDB driver for Ruby, which exposes a simple, elegant, and fast
|
5
5
|
API.
|
6
6
|
|
7
|
+
Project Tracking
|
8
|
+
----------------
|
9
|
+
|
10
|
+
* [Mongoid Google Group](http://groups.google.com/group/mongoid)
|
11
|
+
* [Moped Website and Documentation](http://mongoid.org/en/moped/)
|
12
|
+
|
7
13
|
Compatibility
|
8
14
|
-------------
|
9
15
|
|
10
16
|
Moped is tested against MRI 1.9.2, 1.9.3, 2.0.0, and JRuby (1.9).
|
11
17
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
```ruby
|
16
|
-
session = Moped::Session.new %w[127.0.0.1:27017]
|
17
|
-
session.use "echo_test"
|
18
|
-
|
19
|
-
session.with(safe: true) do |safe|
|
20
|
-
safe[:artists].insert(name: "Syd Vicious"
|
21
|
-
end
|
22
|
-
|
23
|
-
session[:artists].find(name: "Syd Vicious").
|
24
|
-
update(
|
25
|
-
:$push => { instruments: { name: "Bass" } }
|
26
|
-
)
|
27
|
-
```
|
28
|
-
|
29
|
-
## Features
|
30
|
-
|
31
|
-
* Automated replica set node discovery and failover.
|
32
|
-
* No C or Java extensions
|
33
|
-
* No external dependencies
|
34
|
-
* Simple, stable, public API.
|
35
|
-
|
36
|
-
### Unsupported Features
|
37
|
-
|
38
|
-
* GridFS
|
39
|
-
* Map/Reduce
|
40
|
-
|
41
|
-
These features are possible to implement, but outside the scope of Moped's
|
42
|
-
goals. Consider them perfect opportunities to write a companion gem!
|
43
|
-
|
44
|
-
# Project Breakdown
|
45
|
-
|
46
|
-
Moped is composed of three parts: an implementation of the [BSON
|
47
|
-
specification](http://bsonspec.org/), an implementation of the [Mongo Wire
|
48
|
-
Protocol](http://www.mongodb.org/display/DOCS/Mongo+Wire+Protocol), and the
|
49
|
-
driver itself. An overview of the first two follows now, and after that more
|
50
|
-
information about the driver.
|
51
|
-
|
52
|
-
## Moped::BSON
|
53
|
-
|
54
|
-
`Moped::BSON` is the namespace for Moped's BSON implementation. It's
|
55
|
-
implemented in pure (but fast) ruby. The public entry point into the BSON
|
56
|
-
module is `BSON::Document`, which is just subclass of `Hash`, but exposes two
|
57
|
-
class methods: `serialize` and `deserialize`. `serialize` accepts a
|
58
|
-
BSON::Document (or Hash) and returns the serialized BSON representation.
|
59
|
-
`deserialize` does the opposite: it reads data from an IO-like input and
|
60
|
-
returns a deserialized BSON::Document.
|
61
|
-
|
62
|
-
### Moped::BSON::ObjectId
|
63
|
-
|
64
|
-
The `ObjectId` class is used for generating and interacting with Mongo's ids.
|
65
|
-
|
66
|
-
```ruby
|
67
|
-
id = Moped::BSON::ObjectId.new # => 4f8583b5e5a4e46a64000002
|
68
|
-
id.generation_time # => 2012-04-11 13:14:29 UTC
|
69
|
-
id == Moped::BSON::ObjectId.from_string(id.to_s) # => true
|
70
|
-
```
|
71
|
-
|
72
|
-
<table><tbody>
|
73
|
-
|
74
|
-
<tr><th>new</th>
|
75
|
-
<td>Creates a new object id.</td></tr>
|
76
|
-
|
77
|
-
<tr><th>from_string</th>
|
78
|
-
<td>Creates a new object id from an object id string.
|
79
|
-
<br>
|
80
|
-
<code>Moped::BSON::ObjectId.from_string("4f8d8c66e5a4e45396000009")</code>
|
81
|
-
</td></tr>
|
82
|
-
|
83
|
-
<tr><th>from_time</th>
|
84
|
-
<td>Creates a new object id from a time.
|
85
|
-
<br>
|
86
|
-
<code>Moped::BSON::ObjectId.from_time(Time.new)</code>
|
87
|
-
</td></tr>
|
88
|
-
|
89
|
-
<tr><th>legal?</th>
|
90
|
-
<td>Validates an object id string.
|
91
|
-
<br>
|
92
|
-
<code>Moped::BSON::ObjectId.legal?("4f8d8c66e5a4e45396000009")</code>
|
93
|
-
</td></tr>
|
94
|
-
|
95
|
-
</tbody></table>
|
96
|
-
|
97
|
-
### Moped::BSON::Code
|
98
|
-
|
99
|
-
The `Code` class is used for working with javascript on the server.
|
100
|
-
|
101
|
-
```ruby
|
102
|
-
Moped::BSON::Code.new("function () { return this.name }")
|
103
|
-
Moped::BSON::Code.new("function (s) { return s.prefix + this.name }",
|
104
|
-
prefix: "_"
|
105
|
-
)
|
106
|
-
```
|
107
|
-
|
108
|
-
### Moped::BSON::Binary
|
109
|
-
|
110
|
-
The `Binary` class allows you to persist binary data to the server, and
|
111
|
-
supports the following types: `:generic`, `:function`, `:old`, `:uuid`, `:md5`,
|
112
|
-
and `:user`. Note that `:old` is deprecated, but still present to support
|
113
|
-
legacy data.
|
114
|
-
|
115
|
-
```ruby
|
116
|
-
Moped::BSON::Binary.new(:md5, Digest::MD5.digest(__FILE__))
|
117
|
-
```
|
118
|
-
|
119
|
-
## Moped::Protocol
|
120
|
-
|
121
|
-
`Moped::Protocol` is the namespace for Moped's implementation of the Mongo Wire
|
122
|
-
Protocol. Its public API consists of classes representing each type of message
|
123
|
-
in the protocol: `Delete`, `GetMore`, `Insert`, `KillCursors`, `Query`,
|
124
|
-
`Reply`, `Update`, and a convenience class `Command`.
|
125
|
-
|
126
|
-
You should never have to worry about protocol objects, but more details can be
|
127
|
-
found in the API documentation if you're interested.
|
128
|
-
|
129
|
-
# Driver API
|
130
|
-
|
131
|
-
This is the core, public API for Moped. It lives almost entirely in four classes:
|
132
|
-
|
133
|
-
* `Session`: the root object for all interactions with mongo (c.f., `db` in the
|
134
|
-
mongo shell).
|
135
|
-
* `Collection`: for working with collections in the context of a session
|
136
|
-
* `Indexes`: for manipulating and inspecting a collection's indexes
|
137
|
-
* `Query`: for querying, as well as modifying existing data.
|
138
|
-
|
139
|
-
What follows is a "whirlwind" overview of the Moped driver API. For details on
|
140
|
-
additional options, and more examples, use the [generated API
|
141
|
-
docs](http://rubydoc.info/github/mongoid/moped/master/frames).
|
142
|
-
|
143
|
-
## Session
|
144
|
-
|
145
|
-
### Example
|
146
|
-
```ruby
|
147
|
-
session = Moped::Session.new %w[127.0.0.1:27017 127.0.0.1:27018 127.0.0.1:27019]
|
148
|
-
session.use :moped_test
|
149
|
-
session.command ping: 1 # => {"ok"=>1.0}
|
150
|
-
|
151
|
-
session.with(safe: { w: 2, wtimeout: 5 }) do |safe_session|
|
152
|
-
safe_session[:users].find.remove_all
|
153
|
-
end
|
154
|
-
|
155
|
-
session.with(database: "important_db", consistency: :strong) do |session|
|
156
|
-
session[:users].find.one
|
157
|
-
end
|
158
|
-
```
|
159
|
-
|
160
|
-
### API
|
161
|
-
<table><tbody>
|
162
|
-
|
163
|
-
<tr><th>use</th>
|
164
|
-
<td>Set the current database<br>
|
165
|
-
<code>session.use :my_app_test</code></td></tr>
|
166
|
-
|
167
|
-
<tr><th>with</th>
|
168
|
-
<td>Return or yield a copy of session with different options.<br>
|
169
|
-
<code>session.with(safe: true) { |s| ... }</code><br>
|
170
|
-
<code>session.with(database: "admin").command(...)</code></td></tr>
|
171
|
-
|
172
|
-
<tr><th>[]</th>
|
173
|
-
<td>Choose a collection in the current database.<br>
|
174
|
-
<code>session[:people]</code></td></tr>
|
175
|
-
|
176
|
-
<tr><th>drop</th>
|
177
|
-
<td>Drop the current database<br>
|
178
|
-
<code>session.drop</code></td></tr>
|
179
|
-
|
180
|
-
<tr><th>command</th>
|
181
|
-
<td>Run a command on the current database.<br>
|
182
|
-
<code>session.command(ping: 1)</code></td></tr>
|
183
|
-
|
184
|
-
<tr><th>login</th>
|
185
|
-
<td>Log in to the current database.<br>
|
186
|
-
<code>session.login(username, password)</code></td></tr>
|
187
|
-
|
188
|
-
<tr><th>logout</th>
|
189
|
-
<td>Log out from the current database.<br>
|
190
|
-
<code>session.logout</code></td></tr>
|
191
|
-
|
192
|
-
</tbody></table>
|
193
|
-
|
194
|
-
## Collection
|
195
|
-
|
196
|
-
### Example
|
197
|
-
```ruby
|
198
|
-
users = session[:users]
|
199
|
-
users.drop
|
200
|
-
users.find.count # => 0.0
|
201
|
-
|
202
|
-
users.indexes.create({name: 1}, {unique: true})
|
203
|
-
|
204
|
-
users.insert(name: "John")
|
205
|
-
users.find.count # => 1.0
|
206
|
-
|
207
|
-
users.insert(name: "John")
|
208
|
-
users.find.count # => 1.0
|
209
|
-
|
210
|
-
session.with(safe: true) do |session|
|
211
|
-
session[:users].insert(name: "John")
|
212
|
-
end # raises Moped::Errors::OperationFailure
|
213
|
-
```
|
214
|
-
|
215
|
-
### API
|
216
|
-
<table><tbody>
|
217
|
-
|
218
|
-
<tr><th>drop</th>
|
219
|
-
<td>Drop the collection<br>
|
220
|
-
<code>users.drop</code></td></tr>
|
221
|
-
|
222
|
-
<tr><th>indexes</th>
|
223
|
-
<td>Access information about this collection's indexes<br>
|
224
|
-
<code>users.indexes</code></td></tr>
|
225
|
-
|
226
|
-
<tr><th>find</th>
|
227
|
-
<td>Build a query on the collection<br>
|
228
|
-
<code>users.find(name: "John")</code></td></tr>
|
229
|
-
|
230
|
-
<tr><th>insert</th>
|
231
|
-
<td>Insert one or multiple documents.<br>
|
232
|
-
<code>users.insert(name: "John")</code><br>
|
233
|
-
<code>users.insert([{name: "John"}, {name: "Mary"}])</code></td></tr>
|
234
|
-
|
235
|
-
</tbody></table>
|
236
|
-
|
237
|
-
## Index
|
238
|
-
|
239
|
-
### Example
|
240
|
-
```ruby
|
241
|
-
session[:users].indexes.create(name: 1)
|
242
|
-
session[:users].indexes.create(
|
243
|
-
{ name: 1, location: "2d" },
|
244
|
-
{ unique: true }
|
245
|
-
)
|
246
|
-
session[:users].indexes[name: 1]
|
247
|
-
# => {"v"=>1, "key"=>{"name"=>1}, "ns"=>"moped_test.users", "name"=>"name_1" }
|
248
|
-
|
249
|
-
session[:users].indexes.drop(name: 1)
|
250
|
-
session[:users].indexes[name: 1] # => nil
|
251
|
-
```
|
252
|
-
|
253
|
-
### API
|
254
|
-
<table><tbody>
|
255
|
-
|
256
|
-
<tr><th>[]</th>
|
257
|
-
<td>Get an index by its spec.<br>
|
258
|
-
<code>indexes[id: 1]</code></td></tr>
|
259
|
-
|
260
|
-
<tr><th>create</th>
|
261
|
-
<td>Create an index<br>
|
262
|
-
<code>indexes.create({name: 1}, {unique: true})</code></td></tr>
|
263
|
-
|
264
|
-
<tr><th>drop</th>
|
265
|
-
<td>Drop one or all indexes<br>
|
266
|
-
<code>indexes.drop</code><br>
|
267
|
-
<code>indexes.drop(name: 1)</code></td></tr>
|
268
|
-
|
269
|
-
<tr><th>each</th>
|
270
|
-
<td>Yield each index<br>
|
271
|
-
<code>indexes.each { |idx| }</code></td></tr>
|
272
|
-
|
273
|
-
</tbody></table>
|
274
|
-
|
275
|
-
## Query
|
276
|
-
|
277
|
-
### Example
|
278
|
-
```ruby
|
279
|
-
users = session[:users]
|
280
|
-
|
281
|
-
users.insert(name: "John")
|
282
|
-
users.find.count # => 1
|
283
|
-
|
284
|
-
users.find(name: "Mary").upsert(name: "Mary")
|
285
|
-
users.find.count # => 2
|
286
|
-
|
287
|
-
users.find.skip(1).limit(1).sort(name: -1).one
|
288
|
-
# => {"_id" => <...>, "name" => "John" }
|
289
|
-
|
290
|
-
scope = users.find(name: "Mary").select(_id: 0, name: 1)
|
291
|
-
scope.one # => {"name" => "Mary" }
|
292
|
-
scope.remove
|
293
|
-
scope.one # nil
|
294
|
-
```
|
295
|
-
|
296
|
-
### API
|
297
|
-
<table><tbody>
|
298
|
-
|
299
|
-
<tr><th>limit</th>
|
300
|
-
<td>Set the limit for this query.<br>
|
301
|
-
<code>query.limit(5)</code></td></tr>
|
302
|
-
|
303
|
-
<tr><th>skip</th>
|
304
|
-
<td>Set the offset for this query.<br>
|
305
|
-
<code>query.skip(5)</code></td></tr>
|
306
|
-
|
307
|
-
<tr><th>sort</th>
|
308
|
-
<td>Sort the results of the query<br>
|
309
|
-
<code>query.sort(name: -1)</code></td></tr>
|
310
|
-
|
311
|
-
<tr><th>distinct</th>
|
312
|
-
<td>Get the distinct values for a field.<br>
|
313
|
-
<code>query.distinct(:name)</code></td></tr>
|
314
|
-
|
315
|
-
<tr><th>select</th>
|
316
|
-
<td>Select a set of fields to return.<br>
|
317
|
-
<code>query.select(_id: 0, name: 1)</code></td></tr>
|
318
|
-
|
319
|
-
<tr><th>one/first</th>
|
320
|
-
<td>Return the first result from the query.<br>
|
321
|
-
<code>query.one</code></td></tr>
|
322
|
-
|
323
|
-
<tr><th>each</th>
|
324
|
-
<td>Iterate through the results of the query.<br>
|
325
|
-
<code>query.each { |doc| }</code></td></tr>
|
326
|
-
|
327
|
-
<tr><th>count</th>
|
328
|
-
<td>Return the number of documents matching the query.<br>
|
329
|
-
<code>query.count</code></td></tr>
|
330
|
-
|
331
|
-
<tr><th>update</th>
|
332
|
-
<td>Update the first document matching the query's selector.<br>
|
333
|
-
<code>query.update(name: "John")</code></td></tr>
|
334
|
-
|
335
|
-
<tr><th>update_all</th>
|
336
|
-
<td>Update all documents matching the query's selector.<br>
|
337
|
-
<code>query.update_all(name: "John")</code></td></tr>
|
338
|
-
|
339
|
-
<tr><th>upsert</th>
|
340
|
-
<td>Create or update a document using query's selector.<br>
|
341
|
-
<code>query.upsert(name: "John")</code></td></tr>
|
342
|
-
|
343
|
-
<tr><th>remove</th>
|
344
|
-
<td>Remove a single document matching the query's selector.<br>
|
345
|
-
<code>query.remove</code></td></tr>
|
346
|
-
|
347
|
-
<tr><th>remove_all</th>
|
348
|
-
<td>Remove all documents matching the query's selector.<br>
|
349
|
-
<code>query.remove_all</code></td></tr>
|
350
|
-
|
351
|
-
</tbody></table>
|
352
|
-
|
353
|
-
# Exceptions
|
354
|
-
|
355
|
-
Here's a list of the exceptions generated by Moped.
|
356
|
-
|
357
|
-
<table><tbody>
|
358
|
-
|
359
|
-
<tr><th>Moped::Errors::ConnectionFailure</th>
|
360
|
-
<td>Raised when a node cannot be reached or a connection is lost.
|
361
|
-
<br>
|
362
|
-
<strong>Note:</strong> this exception is only raised if Moped could not
|
363
|
-
reconnect, so you shouldn't attempt to rescue this.</td></tr>
|
364
|
-
|
365
|
-
<tr><th>Moped::Errors::OperationFailure</th>
|
366
|
-
<td>Raised when a command fails or is invalid, such as when an insert fails in
|
367
|
-
safe mode.</td></tr>
|
368
|
-
|
369
|
-
<tr><th>Moped::Errors::QueryFailure</th>
|
370
|
-
<td>Raised when an invalid query was sent to the database.</td></tr>
|
371
|
-
|
372
|
-
<tr><th>Moped::Errors::AuthenticationFailure</th>
|
373
|
-
<td>Raised when invalid credentials were passed to `session.login`.</td></tr>
|
374
|
-
|
375
|
-
<tr><th>Moped::Errors::SocketError</th>
|
376
|
-
<td>Not a real exception, but a module used to tag unhandled exceptions inside
|
377
|
-
of a node's networking code. Allows you to `rescue Moped::SocketError` which
|
378
|
-
preserving the real exception.</td></tr>
|
379
|
-
|
380
|
-
</tbody></table>
|
381
|
-
|
382
|
-
Other exceptions are possible while running commands, such as IO Errors around
|
383
|
-
failed connections. Moped tries to be smart about managing its connections,
|
384
|
-
such as checking if they're dead before executing a command; but those checks
|
385
|
-
aren't foolproof, and Moped is conservative about handling unexpected errors on
|
386
|
-
its connections. Namely, Moped will *not* retry a command if an unexpected
|
387
|
-
exception is raised. Why? Because it's impossible to know whether the command
|
388
|
-
was actually received by the remote Mongo instance, and without domain
|
389
|
-
knowledge it cannot be safely retried.
|
390
|
-
|
391
|
-
Take for example this case:
|
392
|
-
|
393
|
-
```ruby
|
394
|
-
session.with(safe: true)["users"].insert(name: "John")
|
395
|
-
```
|
396
|
-
|
397
|
-
It's entirely possible that the insert command will be sent to Mongo, but the
|
398
|
-
connection gets closed before we read the result for `getLastError`. In this
|
399
|
-
case, there's no way to know whether the insert was actually successful!
|
400
|
-
|
401
|
-
If, however, you want to gracefully handle this in your own application, you
|
402
|
-
could do something like:
|
403
|
-
|
404
|
-
```ruby
|
405
|
-
document = { _id: Moped::BSON::ObjectId.new, name: "John" }
|
406
|
-
|
407
|
-
begin
|
408
|
-
session["users"].insert(document)
|
409
|
-
rescue Moped::Errors::SocketError
|
410
|
-
session["users"].find(_id: document[:_id]).upsert(document)
|
411
|
-
end
|
412
|
-
```
|
413
|
-
|
414
|
-
# Replica Sets
|
415
|
-
|
416
|
-
Moped has full support for replica sets including automatic failover and node
|
417
|
-
discovery.
|
418
|
-
|
419
|
-
## Automatic Failover
|
420
|
-
|
421
|
-
Moped will automatically retry lost connections and attempt to detect dead
|
422
|
-
connections before sending an operation. Note, that it will *not* retry
|
423
|
-
individual operations! For example, these cases will work and not raise any
|
424
|
-
exceptions:
|
425
|
-
|
426
|
-
```ruby
|
427
|
-
session[:users].insert(name: "John")
|
428
|
-
# kill primary node and promote secondary
|
429
|
-
session[:users].insert(name: "John")
|
430
|
-
session[:users].find.count # => 2.0
|
431
|
-
|
432
|
-
# primary node drops our connection
|
433
|
-
session[:users].insert(name: "John")
|
434
|
-
```
|
435
|
-
|
436
|
-
However, you'll get an operation error in a case like:
|
437
|
-
|
438
|
-
```ruby
|
439
|
-
# primary node goes down while reading the reply
|
440
|
-
session.with(safe: true)[:users].insert(name: "John")
|
441
|
-
```
|
442
|
-
|
443
|
-
And you'll get a connection error in a case like:
|
444
|
-
|
445
|
-
```ruby
|
446
|
-
# primary node goes down, no new primary available yet
|
447
|
-
session[:users].insert(name: "John")
|
448
|
-
```
|
449
|
-
|
450
|
-
If your session is running with eventual consistency, read operations will
|
451
|
-
never raise connection errors as long as any secondary or primary node is
|
452
|
-
running. The only case where you'll see a connection failure is if a node goes
|
453
|
-
down while attempting to retrieve more results from a cursor, because cursors
|
454
|
-
are tied to individual nodes.
|
18
|
+
Documentation
|
19
|
+
-------------
|
455
20
|
|
456
|
-
|
457
|
-
|
458
|
-
seconds). Note that the `:down_interval` only applies to normal operations;
|
459
|
-
that is, if you ask for a primary node and none is available, all nodes will be
|
460
|
-
retried. Likewise, if you ask for a secondary node, and no secondary or primary
|
461
|
-
node is available, all nodes will be retreied.
|
21
|
+
Please see the new Mongoid website for up-to-date documentation in
|
22
|
+
the Moped section: [mongoid.org](http://mongoid.org/en/moped/)
|
462
23
|
|
463
|
-
|
24
|
+
License
|
25
|
+
-------
|
464
26
|
|
465
|
-
|
466
|
-
replica set connections. After connection, each seed node will return a list of
|
467
|
-
other known nodes which will be added to the set.
|
27
|
+
Copyright (c) 2011-2012 Bernerd Schaefer
|
468
28
|
|
469
|
-
|
470
|
-
|
471
|
-
|
29
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
30
|
+
a copy of this software and associated documentation files (the
|
31
|
+
"Software"), to deal in the Software without restriction, including
|
32
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
33
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
34
|
+
permit persons to whom the Software is furnished to do so, subject to
|
35
|
+
the following conditions:
|
472
36
|
|
473
|
-
|
37
|
+
The above copyright notice and this permission notice shall be
|
38
|
+
included in all copies or substantial portions of the Software.
|
474
39
|
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
40
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
41
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
42
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
43
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
44
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
45
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
46
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
479
47
|
|
480
|
-
|
481
|
-
|
482
|
-
complexity out of the internal API, specifically around replica sets and
|
483
|
-
failover. We've decided that, for now, it's not worth making the replica set
|
484
|
-
code thread-safe.
|
48
|
+
Credits
|
49
|
+
-------
|
485
50
|
|
486
|
-
|
51
|
+
Bernerd Schaefer bj schaefer at gmail dot com
|