我试图在 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
自然地,我想要一个 Ruby 中的磁盘支持队列,它不会破坏我的可用内存,我将它与 Anemone 网络蜘蛛框架一起使用,默认情况下使用Queue
该类,有一个可以使用SizedQueue
该类的 fork,但是当使用aSizedQueue
对于“页面队列”和“链接队列”,它经常死锁,大概是因为它试图使一个页面出队并处理它,并且它找到了新的链接,这种情况无法调和。
还有一个 Redis 队列的现有实现,但是这也耗尽了我在这台机器上的所有可用内存(可用内存为 16Gb,所以这不是微不足道的)
正因为如此,我想使用这个 MongoDB 后端,但我认为实现很疯狂。感觉就像一个可怕的Thread.pass
解决方案,但 Anemone 是多线程的,而且 MongoDB 不支持阻塞读取,所以这是一个棘手的情况。
以下是我的参考资料:
anemone 的 Redis 队列实现:https ://github.com/chriskite/anemone/blob/queueadapter/lib/anemone/queue/redis.rb
MongoDB findAndModify:http ://www.mongodb.org/display/DOCS/findAndModify+Command
问题:
- 任何人都可以评论这是多么理智,相比之下
sleep
(这应该触发VM将控制权传递给下一个线程,无论如何,但sleep
感觉更脏) - 我应该也许
Thread.pass
和sleep
?(我猜不是,见上文) - 我可以从 MongoDB 块中读取吗?这里有人谈论过,但从未谈过任何事情:https ://groups.google.com/forum/?fromgroups=#!topic/mongodb-user/rqnHNFXaZ0w