在Ruby MongoDB驱动程序中阻止findAndModify

在Ruby MongoDB驱动程序中阻止findAndModify,ruby,mongodb,queue,mongoid,Ruby,Mongodb,Queue,Mongoid,我试图在MonogDB中实现类似的功能: require 'base64' require 'mongo' class MongoDBQueue def enq(thing) collection.insert({ payload: Base64.encode64(Marshal.dump(thing))}) end alias :<< :enq def deq until _r = collection.find_and_modify({ so

我试图在MonogDB中实现类似的功能:

require 'base64'
require 'mongo'

class MongoDBQueue

  def enq(thing)
    collection.insert({ payload: Base64.encode64(Marshal.dump(thing))})
  end
  alias :<< :enq

  def deq
    until _r = collection.find_and_modify({ sort: {_id: Mongo::ASCENDING}, remove: true})
      Thread.pass
    end
    return Marshal.load(Base64.decode64(_r["payload"]))
  end
  alias :pop :deq

  private

    def collection
      # database, collection & mongodb index semantics here
    end

end
需要“base64”
需要“mongo”
MongoDBQueue类
def enq(事物)
collection.insert({payload:Base64.encode64(Marshal.dump(thing))})
结束
别名:1)MongoDB中的读取被阻塞。如果执行findOne()或findAndModify(),则在数据出现在客户端之前,调用不会返回。如果执行find(),则在获得游标之前不会返回调用:然后可以根据需要在游标上迭代


2) 默认情况下,对MongoDB的写入是“触发并忘记”。如果您关心数据完整性,则需要通过在连接、数据库或集合对象内核中设置:safe=>true来执行安全写入。实际上,睡眠是一个更好的解决方案,否则您将在那里旋转(尽管在每次查询后将控制权传递给其他线程)。
由于findAndModify是原子的,只有一个线程(即使在JRuby上)将接受该任务,因此我不太明白这里的“阻塞”问题是什么。

是什么让您认为MongoDB不支持阻塞读取?如果执行find_one()或find_and_modify(),则在查询完成之前,操作不会返回&结果返回到客户端。您需要执行“安全模式”写入才能进行阻塞写入。William,如何将上述代码更改为阻塞读取?(我将阻塞定义为在结果满足查询之前不返回)简单地执行>>直到_r=collection.find_和_modify({sort:{u id:Mongo::ASCENDING},remove:true})似乎是William,一直在做更多的工作,代码在-MongoDB还没有通过所有测试,但Redis one是完美的。我不想睡觉,我想“停止”并等待查询返回一个文档,如果没有文档,我想在这里停止线程并确保在有文档之前它不会返回。我想避免睡觉,因为在Ruby中,人能睡的最短时间是0.1s(可靠地),这是不必要的时间开销。我希望Mongo在文档匹配该查询之前不要从该调用返回。