Uploaded image for project: 'C++ Driver'
  1. C++ Driver
  2. CXX-2126

Error "cannot run getMore on cursor" is occasionally thrown

    • Type: Icon: Bug Bug
    • Resolution: Works as Designed
    • Priority: Icon: Major - P3 Major - P3
    • None
    • Affects Version/s: 3.4.0
    • Component/s: API
    • None
    • Environment:
      Windows 10

      Occasionally, running getMore command on a cursor would throw the following error:

      • errmsg: Cannot run getMore on cursor <CURSOR_ID>, which was created in session <SESSION_ID>, in session <SESSION_ID>
      • err_code: 3
      • code: 50738
      • codeName: Location50738

       

      Example Code:

      #include "mongocxx/instance.hpp"
      
      #include <vector>
      #include <thread>
      #include <exception>
      #include <atomic>
      
      int main()
      {
          const int ITERATIONS = 100;           // you might need to increase the number of iterations
          const int DOCS_COUNT = 300;       // the collection has 300 docs, more than the 101 of 1st batch
          const int THREADS_COUNT = 2;    // at least 2 threads are needed
      
          mongocxx::instance instance{};
          mongocxx::pool pool{ mongocxx::uri{} };
      
          std::atomic<ptrdiff_t> num_docs = 0;
          std::vector<std::thread> threads{};
      
          for (int t = 0; t < THREADS_COUNT; ++t)
          {
              threads.emplace_back([&pool, &num_docs, &ITERATIONS]() {
                  auto client = pool.acquire();
                  auto db = (*client)["DatabaseName"];
                  for (int i = 0; i < ITERATIONS; ++i)
                  {
                      auto cmd = bsoncxx::from_json("{\"find\" : \"CollectionName\"}");
                      while (true)
                      {
                          auto ret = db.run_command(cmd.view());
                          auto view = ret.view();
                          bsoncxx::document::element cur{ view["cursor"] };
                          if (cur)
                          {
                              auto res = cur["firstBatch"];
                              if (!res)
                              {
                                  res = cur["nextBatch"];
                                  if (!res)
                                      break;
                              }
                              if (res.type() != bsoncxx::type::k_array)
                                  throw std::exception("Result is not an array!");
                              bsoncxx::array::view subarr{ res.get_array().value };
                              std::atomic_fetch_add(&num_docs, std::distance(std::begin(subarr), std::end(subarr)));
                              auto id = cur["id"].get_int64();
                              if (id == 0)
                                  break;
                              std::string cmd2_str = "{\"getMore\" : " + std::to_string(id) + ", \"collection\" : \"CollectionName\"}";
                              cmd = bsoncxx::from_json(cmd2_str);
                          }
                      }
                  }
              });
          }
      
          for (auto& thread : threads)
              thread.join();
      
          if (ITERATIONS * DOCS_COUNT * THREADS_COUNT != num_docs)
              throw std::exception("Count is not as expected!");
      }
      

       
      Related question:

      Are different connections allowed to use the same implicit session or not? In other words, can a cursor ID returned by a find command be used with a getMore command but using a different implicit session? This doesn't seem to be well documented.

            Assignee:
            clyde.bazile@mongodb.com Clyde Bazile III (Inactive)
            Reporter:
            malik.mokhadri@inmation.com Malik Mokhadri
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: