I am trying to create an oplog watcher in ruby. So far ive come up with a small script below.
require 'rubygems'
require 'mongo'
db = Mongo::Connection.new("localhost", 5151).db("local")
coll = db.collection('oplog.$main')
loop do
cursor = Mongo::Cursor.new(coll, :tailable => true)
while not cursor.closed?
if doc = cursor.next_document
puts doc
else
sleep 1
end
end
end
The problem with this is, after 5 or 6 seconds when it has spit out a lot of data it times out and i get an error
C:/RailsInstaller/Ruby1.8.7/lib/ruby/gems/1.8/gems/mongo-1.4.0/lib/../lib/mongo/connection.rb
:807:in `check_response_flags': Query response returned CURSOR_NOT_FOUND. Either an invalid c
ursor was specified, or the cursor may have timed out on the server. (Mongo::OperationFailure
)
from C:/RailsInstaller/Ruby1.8.7/lib/ruby/gems/1.8/gems/mongo-1.4.0/lib/../lib/mongo/
connection.rb:800:in `receive_response_header'
from C:/RailsInstaller/Ruby1.8.7/lib/ruby/gems/1.8/gems/mongo-1.4.0/lib/../lib/mongo/
connection.rb:768:in `receive'
from C:/RailsInstaller/Ruby1.8.7/lib/ruby/gems/1.8/gems/mongo-1.4.0/lib/../lib/mongo/
connection.rb:493:in `receive_message'
from C:/RailsInstaller/Ruby1.8.7/lib/ruby/gems/1.8/gems/mongo-1.4.0/lib/../lib/mongo/
connection.rb:491:in `synchronize'
from C:/RailsInstaller/Ruby1.8.7/lib/ruby/gems/1.8/gems/mongo-1.4.0/lib/../lib/mongo/
connection.rb:491:in `receive_message'
from C:/RailsInstaller/Ruby1.8.7/lib/ruby/gems/1.8/gems/mongo-1.4.0/lib/../lib/mongo/
cursor.rb:494:in `send_get_more'
from C:/RailsInstaller/Ruby1.8.7/lib/ruby/gems/1.8/gems/mongo-1.4.0/lib/../lib/mongo/
cursor.rb:456:in `refresh'
from C:/RailsInstaller/Ruby1.8.7/lib/ruby/gems/1.8/gems/mongo-1.4.0/lib/../lib/mongo/
cursor.rb:124:in `next_document'
from n.rb:7
from n.rb:6:in `loop'
from n.rb:6
What i dont understand is when i m able to see the actual data how can it suddenly say cursor not found. Im pretty new to ruby and any ideas on what direction i must take will be useful for me.
Give Feedback. By default, MongoDB will automatically close a cursor when the client has exhausted all results in the cursor. However, for capped collections you may use a Tailable Cursor that remains open after the client exhausts the results in the initial cursor.
In MongoDB, when the find() method is used to find the documents present in the given collection, then this method returned a pointer which will points to the documents of the collection, now this pointer is known as cursor.
collection. find() to search documents in collections then as a result it returns a pointer. That pointer is known as a cursor. Consider if we have 2 documents in our collection, then the cursor object will point to the first document and then iterate through all documents which are present in our collection.
Find() Method. In MongoDB, find() method is used to select documents in a collection and return a cursor to the selected documents. Cursor means a pointer that points to a document, when we use find() method it returns a pointer on the selected documents and returns one by one.
The solution is that i need to have an exception handling mechanism to capture the exception which is thrown when the cursor reads the last document in a relatively small oplog with an higher number of writes per second. Since the cursor reaches the end of the oplog it would throw an exception that there are no more records.
require 'rubygems'
require 'mongo'
db = Mongo::Connection.new("localhost",5151).db("local")
coll = db.collection('oplog.$main')
loop do
cursor = Mongo::Cursor.new(coll, :timeout => false, :tailable => true)
while not cursor.closed?
begin
if doc = cursor.next_document
puts "Timestamp"
puts doc["ts"]
puts "Record"
puts doc["o"]
puts "Affected Collection"
puts doc["ns"]
end
rescue
puts ""
break
end
end
end
This now works as the exception is been handled. Thanks to the mongodb-user google group for pointing this out to me.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With