Skip to content

Instantly share code, notes, and snippets.

@maccman

maccman/mongo.rb Secret

Created August 8, 2012 02:16
Show Gist options
  • Save maccman/20e49e0282783c4f5603 to your computer and use it in GitHub Desktop.
Save maccman/20e49e0282783c4f5603 to your computer and use it in GitHub Desktop.
require 'fiber'
module EventMachine
module Deferrable
def wait
fiber = Fiber.current
self.errback {|err| p err }
self.callback {|cb| fiber.resume(cb) }
Fiber.yield
end
end
end
module EM::Mongo
class FiberDatabase < Database
def authenticate(*args)
super(*args).wait
end
end
class FiberConnection < Connection
def initialize(*args)
fiber = Fiber.current
super(*args)
# establish connection before returning
EM.next_tick { fiber.resume }
Fiber.yield
end
end
class FiberCollection < EM::Mongo::Collection
%w{
safe_insert
safe_update
find_and_modify
map_reduce
distinct
group
drop_index
insert_documents
safe_send
index_name
}.each do |name|
class_eval <<-EOF
def #{name}(*args)
super(*args).wait
end
EOF
end
alias :afind :find
def find(*args)
super(*args).to_a.wait
end
def find_one(selector = {}, opts = {})
opts[:limit] = 1
find(selector, opts).first
end
alias :first :find_one
def count
afind().count.wait
end
end
# Overwrite originals
EM::Mongo::Database = FiberDatabase
EM::Mongo::Connection = FiberConnection
EM::Mongo::Collection = FiberCollection
end
@jgyllen
Copy link

jgyllen commented Aug 15, 2012

I saw your tweet. Nice work. How do you plug this into MongoMapper? Does this API map 1:1 to the mongo/plucky API?

@fl00r
Copy link

fl00r commented Apr 9, 2013

def wait
  fib = Fiber.current
  callback do |res|
    fib.resume(res)
  end
  errback do |err|
    fib.resume(err)
  end
  res = Fiber.yield
  raise res if Exception === res
  res
end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment