-
Type: Improvement
-
Resolution: Won't Do
-
Priority: Unknown
-
None
-
Affects Version/s: None
-
Component/s: None
-
(copied to CRM)
This request is specifically for server-side connection limits being reached and not communicated back to the client application, however other server-side failures could be better reported to clients.
For example, after adapting the connection pooling example as follows:
// file: test.cpp // build: c++ --std=c++11 test.cpp -o test $(pkg-config --cflags --libs libmongocxx) -lpthread #include <iostream> #include <ostream> #include <sstream> #include <thread> #include <vector> #include <bsoncxx/builder/basic/document.hpp> #include <bsoncxx/builder/basic/kvp.hpp> #include <bsoncxx/json.hpp> #include <bsoncxx/types.hpp> #include <mongocxx/client.hpp> #include <mongocxx/instance.hpp> #include <mongocxx/pool.hpp> #include <mongocxx/uri.hpp> using bsoncxx::builder::basic::kvp; int main() { // The mongocxx::instance constructor and destructor initialize and shut down the driver, // respectively. Therefore, a mongocxx::instance must be created before using the driver and // must remain alive for as long as the driver is in use. mongocxx::instance inst{}; mongocxx::uri uri{"mongodb://localhost:27017/?minPoolSize=5&maxPoolSize=5"}; mongocxx::pool pool{uri}; std::vector<std::string> collection_names = {"foo", "bar", "baz"}; std::vector<std::thread> threads{}; for (auto i : {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}) { auto run = [&](std::int64_t j) { // Each client and collection can only be used in a single thread. auto client = pool.acquire(); auto coll = (*client)["test"][collection_names[static_cast<std::size_t>(j)]]; coll.delete_many({}); bsoncxx::types::b_int64 index = {j}; coll.insert_one(bsoncxx::builder::basic::make_document(kvp("x", index))); if (auto doc = (*client)["test"][collection_names[static_cast<std::size_t>(j)]].find_one({})) { // In order to ensure that the newline is printed immediately after the document, // they need to be streamed to std::cout as a single string. std::stringstream ss; ss << bsoncxx::to_json(*doc) << std::endl; std::cout << ss.str(); } // The client goes out of scope at the end of the lambda and is returned to the pool. }; std::thread runner{run, i}; threads.push_back(std::move(runner)); } for (auto&& runner : threads) { runner.join(); } }
And starting up a mongod with a hard limit of 5 simultaneous connections :
m 4.4.9-ent rm -rf data && mkdir data mongod --dbpath data --maxConns 5
The application will fail with:
terminate called after throwing an instance of 'mongocxx::v_noabi::bulk_write_exception' what(): Failed to send "isMaster" command with database "admin": socket error or timeout: generic server error Aborted (core dumped)
The error message is not obviously actionable, though the mongod log in this case contains details that identify the cause of the failure:
{"t":{"$date":"2021-10-05T10:59:55.937-04:00"},"s":"I","c":"NETWORK","id":51800,"ctx":"conn24","msg":"client metadata","attr":{"remote":"127.0.0.1:36876","client":"conn24","doc":{"driver":{"name":"mongoc / mongocxx","version":"1.17.4 / 3.6.2"},"os":{"type":"Linux","name":"Linux Mint","version":"20.2","architecture":"x86_64"},"platform":"(null)cfg=0x02a15ea0e9 posix=200809 stdc=201710 CC=GCC 9.3.0 CFLAGS=\"\" LDFLAGS=\"\""}}}
{"t":{"$date":"2021-10-05T10:59:55.937-04:00"},"s":"I","c":"NETWORK","id":22942,"ctx":"listener","msg":"Connection refused because there are too many open connections","attr":{"connectionCount":6}}