Using tail cursors pymongo dies in empty collections

Hoping someone can help me understand if I see a problem, or if I just don't understand the behavior of the mongodb tail cursor. I am running mongodb 2.0.4 and pymongo 2.1.1.

Here is a script that demonstrates the problem.

#!/usr/bin/python

import sys
import time
import pymongo

MONGO_SERVER = "127.0.0.1"
MONGO_DATABASE = "mdatabase"
MONGO_COLLECTION = "mcollection"

mongodb    = pymongo.Connection(MONGO_SERVER, 27017)
database   = mongodb[MONGO_DATABASE]

if MONGO_COLLECTION in database.collection_names():
  database[MONGO_COLLECTION].drop()

print "creating capped collection"
database.create_collection(
  MONGO_COLLECTION,
  size=100000,
  max=100,
  capped=True
)
collection = database[MONGO_COLLECTION]

# Run this script with any parameter to add one record
# to the empty collection and see the code below
# loop correctly
#
if len(sys.argv[1:]):
  collection.insert(
    {
      "key" : "value",
    }
  )

# Get a tailable cursor for our looping fun
cursor = collection.find( {},
                          await_data=True,
                          tailable=True )

# This will catch ctrl-c and the error thrown if
# the collection is deleted while this script is
# running.
try:

  # The cursor should remain alive, but if there
  # is nothing in the collection, it dies after the
  # first loop. Adding a single record will
  # keep the cursor alive forever as I expected.
  while cursor.alive:
    print "Top of the loop"
    try:
      message = cursor.next()
      print message
    except StopIteration:
      print "MongoDB, why you no block on read?!"
      time.sleep(1)

except pymongo.errors.OperationFailure:
  print "Delete the collection while running to see this."

except KeyboardInterrupt:
  print "trl-C Ya!"
  sys.exit(0)

print "and we're out"

# End

So, if you look at the code, it’s pretty simple to demonstrate the problem I am facing. When I run the code against an empty collection (properly closed and ready for the tail), the cursor dies and my code exits after one loop. Adding the first entry to the collection makes it behave as I would expect if the tail cursor acted.

, StopIteration, .next(), ? , ? , await_data - , , , .

, While True cursor.alive, , script , , CPU. , .

+3
1

, 2 "" . , , , , , ( , ).

+1

All Articles