[CXX-1353] Tail cursor block thread after network switching Created: 31/May/17  Updated: 27/Oct/23  Resolved: 02/Jun/17

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

Type: Task Priority: Minor - P4
Reporter: Denis Bip Assignee: Unassigned
Resolution: Works as Designed Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

debian 8.6



 Description   

Hello! When I run tail cursor in while loop and disable network adapter for a few minutes the thread that reading tail cursor become blocked. Version is 3.1.1 with custom update for tail cursors work

mongocxx::stdx::optional<mongocxx::pool::entry> sc = try_get_connection_from_pool(connection_name);
    if (sc == mongocxx::stdx::nullopt) throw std::runtime_error("cant get connection from pool");
    mongocxx::client* conn = sc->get();
 
    try
    {
        auto db = (*conn)[connection_name];
        mongocxx::collection coll = db[collection];
 
        bsoncxx::document::value f = bsoncxx::from_json(json);
 
        mongocxx::options::find options;
        options.cursor_type(mongocxx::cursor::type::k_tailable_await);
 
        mongocxx::cursor cursor = coll.find(f.view(), options);
 
        while(is_running.load(std::memory_order_acquire))
        {
            /*if(cursor.begin() == cursor.end())
            {
                std::this_thread::sleep_for(std::chrono::seconds(1));
                continue;
            }*/
 
            //here its blocked
            for(auto&& doc : cursor)
            {
                mongo::db::fetcher st(doc);
                callback(&st);
            }
 
            if (callback_run) callback_run();
        }
    }
    catch(std::exception& ex)
    {
        throw ex;
    }



 Comments   
Comment by Denis Bip [ 11/Jun/17 ]

Sorry! I forgot to switch to the newest version of library on other project! Works fine

Comment by Denis Bip [ 10/Jun/17 ]

Hi again! When I run this code any capped collection it works, but if I try to run on oplog.rs it works only first ~1-2 minutes and than it stops

Comment by Samuel Rossi (Inactive) [ 02/Jun/17 ]

Awesome! I'm glad we were able to help

Comment by Denis Bip [ 01/Jun/17 ]

Thank you very much! With socketTimeoutMS works fine!

Comment by Samuel Rossi (Inactive) [ 31/May/17 ]

Hi Denis! I've written a small sample program that demonstrates what Jesse suggested in case you want to see it in action:

#include <chrono>
#include <iostream>
#include <thread>
 
#include <bsoncxx/builder/basic/document.hpp>
#include <bsoncxx/builder/basic/kvp.hpp>
#include <bsoncxx/document/value.hpp>
#include <bsoncxx/json.hpp>
#include <mongocxx/client.hpp>
#include <mongocxx/cursor.hpp>
#include <mongocxx/instance.hpp>
#include <mongocxx/options/create_collection.hpp>
#include <mongocxx/options/find.hpp>
#include <mongocxx/uri.hpp>
 
using namespace mongocxx;
 
using bsoncxx::builder::basic::kvp;
 
int main() {
    instance inst{};
    client conn{uri{"mongodb://some_host/?socketTimeoutMS=5000"}};
    auto db = conn["some_db"];
 
    db["some_coll"].drop();
    db.create_collection(
        "some_coll",
        options::create_collection{}.capped(true).max(10000).size(1024 * 1024));
    auto coll = db["some_coll"];
 
    ///
    /// Add the documents { "x": 0 }, { "x": 1 }, ... { "x" : 9999 } to the
    /// collection.
    ///
 
    std::vector<bsoncxx::document::value> docs;
    bsoncxx::builder::basic::document document;
 
    for (std::int32_t i = 0; i < 10000; ++i) {
        document.append(kvp("x", i));
        docs.push_back(document.extract());
    }
 
    coll.insert_many(docs);
 
    ///
    /// Query each document, waiting half a second between each document.
    ///
 
    for (auto&& doc :
         coll.find({}, options::find{}
                           .cursor_type(cursor::type::k_tailable_await)
                           .batch_size(5))) {
        std::cout << bsoncxx::to_json(doc) << std::endl;
        std::this_thread::sleep_for(std::chrono::milliseconds(500));
    }
}

If you cut off your internet connection while the program is running, it should exit with an error after 5 seconds (plus the time to finish the current batch, which shouldn't be more than a second or two).

Let me know if this doesn't work for you, or if you have any other questions!

Comment by A. Jesse Jiryu Davis [ 31/May/17 ]

The default socketTimeoutMS for the C Driver is 5 minutes, what happens if you include something shorter in your connection string?:

mongodb://my-server.com/?socketTimeoutMS=10000

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