Em-mongo is no longer being maintained (hasn't been for some time). If you are interested in the commit bit
or want to take over the full project, please let me know!

EM-Mongo

An EventMachine client for MongoDB. Originally based on RMongo, this client
aims to be as api compatible with mongo-ruby-driver as possible.

For methods that do not retrieve data from the database the api of em-mongo
should be identical (though a subset) to the mongo-ruby-driver. This
includes the various update methods like insert, save and update (without
the :safe flag, which is handled separately) as well as find, which returns
a cursor.

Some examples

#this file can be found in the examples directory.
# bundle exec examples/readme.rb
#insert a few records, then read some back using Collection#find
require'em-mongo'require'eventmachine'EM.rundodb=EM::Mongo::Connection.new('localhost').db('my_database')collection=db.collection('my_collection')EM.next_tickdo(1..10).eachdo|i|collection.insert({:revolution=>i})end#find returns an EM::Mongo::Cursor
cursor=collection.find#most cursor methods return an EM::Mongo::RequestResponse,
#which is an EventMachine::Deferrable
resp=cursor.defer_as_a#when em-mongo IO methods succeed, they
#will always call back with the return
#value you would have expected from the
#synchronous version of the same method from
#the mongo-ruby-driver
resp.callbackdo|documents|puts"I just got #{documents.length} documents! I'm really cool!"end#when em-mongo IO methods fail, they
#errback with an array in the form
#[ErrorClass, "error message"]
resp.errbackdo|err|raise*errend#iterate though each result in a query
collection.find(:revolution=>{"$gt"=>5}).limit(1).skip(1).eachdo|doc|#unlike the mongo-ruby-driver, each returns null at the end of the cursor
ifdocputs"Revolution ##{doc['revolution']}"endend#add an index
collection.create_index[[:revolution,-1]]#insert a document and ensure it gets written
save_resp=collection.safe_save({:hi=>"there"},:last_error_params=>{:fsync=>true})save_resp.callback{puts"Hi is there, let us give thanks"}save_resp.errback{|err|puts"AAAAAAAAAAAAAAAARGH! Oh why! WHY!?!?!"}collection.dropEM.add_periodic_timer(1){EM.stop}endend

Error handling

em-mongo will present errors in two different ways. First, em-mongo will
raise exceptions like any other synchronous library if an error is
enountered in a method that does not need to perform IO or if an error is
encountered prior to peforming IO.

Errors returned by the database, or errors communicating with the database,
will be delivered via standard EM::Deferrable errbacks. While it is
tempting to subscribe just to a callback

my_collection.find.defer_as_a.callback {|docs| ... }

in the case of an error you will never receive a response. If you are
waiting for a response before your program continues, you will be waiting a
very long time. A better approach would be to store the deferrable into a
variable and subscribe to its callback and errback

errback's blocks will always be called with a single argument which is
a two element array containing the error class and the error message

[EM::Mongo::OperationError,"aw snap"]

Safe Writes

As you are probably aware the default behavior for the mongo-ruby-driver,
and therefore em-mongo, is to send update messages to MongoDB in a
fire-and-forget manner. This means that if a unique index is violated, or
some other problem causes MongoDB to raise an exception and refuse to apply
your changes, you'll never know about it until you go to look for that
record later. For many applications such as logging this might be OK, but
for many use cases like analytics you will want to know if your writes
don't succeed.

This is one place where em-mongo diverges substantially from the
mongo-ruby-driver because an unsafe write will not receive a response from
the server, whereas a safe write will receive a response from the server
and requires a deferrable and a callback.

In addition to calling your errback if the write fails, you can provide the
usual 'safety' options that you can to Database#get_last_error,
such as :fsync => true or :w => 2, to control the degree of safety
you want. Please the 10gen documentation on DB#get_last_error for
specifics.

safe_insert({:a=>"v"},:last_error_params=>{:fsync=>true,:w=>5})

Documentation

em-mongo now has some YARD docs. These are mostly ported directly from the
mongo-ruby-driver. While they have been updated to reflect em-mongo's
async API, there are probably a few errors left over in the translation.
Please file an issue or submit a pull request if you notice any
inaccuracies.

Upgrading

em-mongo methods no longer directly accept callbacks and instead return
EM::Mongo::RequestResponse objects, which are EM::Deferrable(s). This means
you need to convert calls like this

my_collection.first(){|doc|pdoc}

to this

my_collection.first().callback{|doc|pdoc}

EM::Mongo::Collection#find now returns a cursor, not an array, to maintain
compatibility with the mongo-ruby-driver. This provides a great deal more
flexibility, but requires you to select a specific cursor method to
actually fetch data from the server, such as #defer_as_a or #next

my_collection.find() { |docs| ... }

becomes

my_collection.find.defer_as_a.callback { |docs| ... }

If for some reason you aren't ready to upgrade your project but you
want to be able to use the newer gem, you can require a compatibility file
that will revert the new API to the API found in 0.3.6

require'em-mongo'require'em-mongo/prev.rb'

This file will not remain in the project forever, though, so it is better
to upgrade your projects sooner rather than later.

License

Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the ‘Software’),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED ‘AS IS’, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.