@@ -15,6 +15,21 @@ session[:artists].find(name: "Syd Vicious").
1515 )
1616```
1717
18+ ## Features
19+
20+ * Automated replica set node discovery and failover.
21+ * No C or Java extensions
22+ * No external dependencies
23+ * Simple, stable, public API.
24+
25+ ### Unsupported Features
26+
27+ * GridFS
28+ * Map/Reduce
29+
30+ These features are possible to implement, but outside the scope of Moped's
31+ goals. Consider them perfect opportunities to write a companion gem!
32+
1833# Project Breakdown
1934
2035Moped is composed of three parts: an implementation of the [ BSON
@@ -43,6 +58,31 @@ id.generation_time # => 2012-04-11 13:14:29 UTC
4358id == Moped ::BSON ::ObjectId .from_string(id.to_s) # => true
4459```
4560
61+ <table ><tbody >
62+
63+ <tr ><th >new</th >
64+ <td >Creates a new object id.</td ></tr >
65+
66+ <tr ><th >from_string</th >
67+ <td >Creates a new object id from an object id string.
68+ <br >
69+ <code >Moped::BSON::ObjectId.from_string("4f8d8c66e5a4e45396000009")</code >
70+ </td ></tr >
71+
72+ <tr ><th >from_time</th >
73+ <td >Creates a new object id from a time.
74+ <br >
75+ <code >Moped::BSON::ObjectId.from_time(Time.new)</code >
76+ </td ></tr >
77+
78+ <tr ><th >legal?</th >
79+ <td >Validates an object id string.
80+ <br >
81+ <code >Moped::BSON::ObjectId.legal?("4f8d8c66e5a4e45396000009")</code >
82+ </td ></tr >
83+
84+ </tbody ></table >
85+
4686### Moped::BSON::Code
4787
4888The ` Code ` class is used for working with javascript on the server.
@@ -299,6 +339,126 @@ scope.one # nil
299339
300340</tbody ></table >
301341
342+ # Exceptions
343+
344+ Here's a list of the exceptions generated by Moped.
345+
346+ <table ><tbody >
347+
348+ <tr ><th >Moped::Errors::ConnectionFailure</th >
349+ <td >Raised when a node cannot be reached or a connection is lost.
350+ <br >
351+ <strong >Note:</strong > this exception is only raised if Moped could not
352+ reconnect, so you shouldn't attempt to rescue this.</td ></tr >
353+
354+ <tr ><th >Moped::Errors::OperationFailure</th >
355+ <td >Raised when a command fails or is invalid, such as when an insert fails in
356+ safe mode.</td ></tr >
357+
358+ <tr ><th >Moped::Errors::QueryFailure</th >
359+ <td >Raised when an invalid query was sent to the database.</td ></tr >
360+
361+ <tr ><th >Moped::Errors::AuthenticationFailure</th >
362+ <td >Raised when invalid credentials were passed to `session.login`.</td ></tr >
363+
364+ <tr ><th >Moped::Errors::SocketError</th >
365+ <td >Not a real exception, but a module used to tag unhandled exceptions inside
366+ of a node's networking code. Allows you to ` rescue Moped::SocketError ` which
367+ preserving the real exception.</td ></tr >
368+
369+ </tbody ></table >
370+
371+ Other exceptions are possible while running commands, such as IO Errors around
372+ failed connections. Moped tries to be smart about managing its connections,
373+ such as checking if they're dead before executing a command; but those checks
374+ aren't foolproof, and Moped is conservative about handling unexpected errors on
375+ its connections. Namely, Moped will * not* retry a command if an unexpected
376+ exception is raised. Why? Because it's impossible to know whether the command
377+ was actually received by the remote Mongo instance, and without domain
378+ knowledge it cannot be safely retried.
379+
380+ Take for example this case:
381+
382+ ``` ruby
383+ session.with(safe: true )[" users" ].insert(name: " John" )
384+ ```
385+
386+ It's entirely possible that the insert command will be sent to Mongo, but the
387+ connection gets closed before we read the result for ` getLastError ` . In this
388+ case, there's no way to know whether the insert was actually successful!
389+
390+ If, however, you want to gracefully handle this in your own application, you
391+ could do something like:
392+
393+ ``` ruby
394+ document = { _id: Moped ::BSON ::ObjectId .new , name: " John" }
395+
396+ begin
397+ session[" users" ].insert(document)
398+ rescue Moped ::Errors ::SocketError
399+ session[" users" ].find(_id: document[:_id ]).upsert(document)
400+ end
401+ ```
402+
403+ # Replica Sets
404+
405+ Moped has full support for replica sets including automatic failover and node
406+ discovery.
407+
408+ ## Automatic Failover
409+
410+ Moped will automatically retry lost connections and attempt to detect dead
411+ connections before sending an operation. Note, that it will * not* retry
412+ individual operations! For example, these cases will work and not raise any
413+ exceptions:
414+
415+ ``` ruby
416+ session[:users ].insert(name: " John" )
417+ # kill primary node and promote secondary
418+ session[:users ].insert(name: " John" )
419+ session[:users ].find.count # => 2.0
420+
421+ # primary node drops our connection
422+ session[:users ].insert(name: " John" )
423+ ```
424+
425+ However, you'll get an operation error in a case like:
426+
427+ ``` ruby
428+ # primary node goes down while reading the reply
429+ session.with(safe: true )[:users ].insert(name: " John" )
430+ ```
431+
432+ And you'll get a connection error in a case like:
433+
434+ ``` ruby
435+ # primary node goes down, no new primary available yet
436+ session[:users ].insert(name: " John" )
437+ ```
438+
439+ If your session is running with eventual consistency, read operations will
440+ never raise connection errors as long as any secondary or primary node is
441+ running. The only case where you'll see a connection failure is if a node goes
442+ down while attempting to retrieve more results from a cursor, because cursors
443+ are tied to individual nodes.
444+
445+ When two attempts to connect to a node fail, it will be marked as down. This
446+ removes it from the list of available nodes for ` :down_interval ` (default 30
447+ seconds). Note that the ` :down_interval ` only applies to normal operations;
448+ that is, if you ask for a primary node and none is available, all nodes will be
449+ retried. Likewise, if you ask for a secondary node, and no secondary or primary
450+ node is available, all nodes will be retreied.
451+
452+ ## Node Discovery
453+
454+ The addresses you pass into your session are used as seeds for setting up
455+ replica set connections. After connection, each seed node will return a list of
456+ other known nodes which will be added to the set.
457+
458+ This information is cached according to the ` :refresh_interval ` option (default:
459+ 5 minutes). That means, e.g., that if you add a new node to your replica set,
460+ it should be represented in Moped within 5 minutes.
461+
302462# Thread-Safety
303463
304464Moped is thread-safe -- depending on your definition of thread-safe. For Moped,
0 commit comments