Details
-
Bug
-
Resolution: Works as Designed
-
Major - P3
-
None
-
3.4.0
-
None
-
Windows 10
Description
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.