I wonder if it is possible to create a FIFO queue with mongodb and ruby(mongoid).
I am trying to use capped collections but I cannot see how I can pop my queue. There seem to be no methods in collection to do this.
What I am doing right now is:
$fifo = Mongo::Connection.new.db("fifo")
queue = "#{queue_name}_#{queue_type}"
unless $fifo[queue].find.present?
$fifo.command(create: queue, capped: true, size: 10000000, max: 1000)
end
$fifo[queue].insert(url: "http://www.example.com/unique001")
$fifo[queue].insert(url: "http://www.example.com/unique002")
$fifo[queue].insert(url: "http://www.example.com/unique003")
Which gives me a capped collection that looks like (from console)
> db.test001_high.find()
{ "_id" : ObjectId("503c4714236f440e9c000001"), "url" : "http://www.example.com/unique001" }
{ "_id" : ObjectId("503c4714236f440e9c000002"), "url" : "http://www.example.com/unique002" }
{ "_id" : ObjectId("503c4714236f440e9c000003"), "url" : "http://www.example.com/unique003" }
What I wonder is, is there a way in ruby to have a blocking pop on this collection? I must say I am not really familiar with mongodb and am just trying to create a fifo queue like I have in redis. So maybe I am approaching this problem the wrong way.
I implemented a FIFO queue for mongo in Java. You should use the atomic operation findAndModify to find the earliest entry from the queue collection, and remove the document (remove=true) or set a status field.
The other thing to be careful is that you should only be doing this with MasterOnly reads, or set your write-number equal to the number of nodes on write. Otherwise you may get inconsistent result due to replication delay.