zhengchun
zhengchun

Reputation: 1291

'Cursor not found' error when use a Tailable Cursor with NoCursorTimeout

I created a capped collection with a 50M default size. More recently, I noticed that I get a Cursor not found error when a capped collection storage size goes over 50M. I'm not sure what reason causes this: I never get this error before when a capped collection size went less than a default maximum size.

if (this._cursor == null || this._cursor.IsDead)
{                 
   var cursor = this._queueCollection.Find(Query.GT("_id", this._lastId))
            .SetFlags(QueryFlags.AwaitData |
            QueryFlags.TailableCursor |
            QueryFlags.NoCursorTimeout)
            .SetSortOrder(SortBy.Ascending("$natural")); 
    this._cursor =(MongoCursorEnumerator<QueueMessage<T>>)cursor.GetEnumerator();
}

try
{
    if (this._cursor.MoveNext())
        //do some things
        return this._cursor.Current;
    else
     {
         if (this._cursor.IsDead){
               this._cursor.Dispose();
               this._cursor=null;
         }
     }
     return null;
}
catch{}

The this._cursor.MoveNext() will throw a cursor not found exception (occasionally, not always thrown. Is my code wrong?

Upvotes: 2

Views: 1963

Answers (2)

zhengchun
zhengchun

Reputation: 1291

I have found what cause this error.

Tailable cursors may become dead, or invalid, if either:

  1. The query returns no match.
  2. The cursor returns the document at the “end” of the collection and then the application deletes those document.

reference from a mongodb official website about create tailable cursor (http://docs.mongodb.org/manual/tutorial/create-tailable-cursor/)

In my application, when a `cursor not found' exception is thrown it always is because the cursor returns the document at the “end” of the collection and then the application deletes those document.

Upvotes: 2

&#214;mer Faruk Aplak
&#214;mer Faruk Aplak

Reputation: 911

you can use foreach:

var query1 = new QueryBuilder<Message>().GT(m => m.date, lastTransferredMessageDate);
var result = messagesCollection.FindAs<Message>(query1).SetFlags(QueryFlags.NoCursorTimeout);

foreach (var message in result)
{
  // Your code
}

Upvotes: 0

Related Questions