[CSHARP-885] Tail the oplog in C# Created: 02/Jan/14  Updated: 05/Apr/19  Resolved: 20/Mar/14

Status: Closed
Project: C# Driver
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Task Priority: Trivial - P5
Reporter: Ashutosh Assignee: Unassigned
Resolution: Done Votes: 0
Labels: driver, question
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified


 Description   

How can we tail the oplog in C# ?
I found the java example here https://github.com/mongodb/mongo-java-driver/blob/master/examples/ReadOplog.java .
My attempt is here https://gist.github.com/ashutoshraina/8217451.
Does this seem appropriate and correct ?
Is there a plan to make this a first class feature of the driver iteself ?



 Comments   
Comment by Ashutosh [ 17/Jan/14 ]

Yes, it did.

Comment by Robert Stam [ 17/Jan/14 ]

There are no plans to provide any specialized methods for tailing the oplog, other than supporting tailable cursors in general.

Did the code provided in the earlier response not help you?

Comment by Ashutosh [ 17/Jan/14 ]

Haven't heard anything on this from anyone.
Just to add what I have said above. If we have the ability to track a document with the oplog then we can enable interesting scenarios where we don't need to go to the database to check the last changed timestamp of the document (i,.e. optimistic concurrency). We can just send a notification to the client from the server(application) in real-time.

Comment by Ashutosh [ 02/Jan/14 ]

Firstly, apologies for not providing the complete code for compilation.

Shouldn't there be a dedicated api which allows us to work with the oplog since it is a special collection ?
I would probably like to see a syntax which allows for something which is more strongly typed like

database.oplog.where(r => r.ns == "mynamespace")

I do understand that this might be a little tricky since the schema will vary quite a bit for this collection.

Comment by Robert Stam [ 02/Jan/14 ]

I would propose some changes to your sample code, as follows (a few of the changes are just so I could get it to compile without having the rest of your code):

public static void GetLastEntryInOpLog(MongoCollection<BsonDocument> collection)
{
    BsonValue lastId = BsonMinKey.Value;
    while (true)
    {
        var query = Query.GT("ts", lastId);
        var cursor = collection.Find(query)
            .SetFlags(QueryFlags.TailableCursor | QueryFlags.AwaitData)
            .SetSortOrder(SortBy.Ascending("$natural"));
 
        var count = 0;
        foreach (var document in cursor)
        {
            lastId = document["ts"];
            Console.WriteLine("LastId is {0}", lastId);
            Console.WriteLine(document);
            count++;
        }
 
        if (count == 0)
        {
            Thread.Sleep(TimeSpan.FromMilliseconds(100));
        }
    }
}

Notes:

  • You need an outer loop to handle restarting dead tailable cursors
  • You should recompute the query each time through the outer loop so that the current value of lastId gets used
  • You can use foreach instead of the lower level enumerator
  • You might want to throttle back if the cursor is dead initially (i.e. count == 0) to avoid hammering the server (optional)

Note: Edited because I forgot the call to SetFlags and SetSortOrder. I don't think NoCursorTimeout is needed with tailable cursors.

Generated at Wed Feb 07 21:38:06 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.