Don't force Mongo sink to own MongoCXX instance

There can only be one instance in the whole program, so programs that use the
Mongo sink and also separately use MongoCXX may have problems if the Mongo sink
owns the instance. MongoCXX recommends that the main application manage its own
instance so configuration parameters can be passed to the constructor:
http://mongocxx.org/api/current/classmongocxx_1_1instance.html

However, this commit is not a breaking change. If no instance has been created
at construction time, the Mongo sink will still create and own the instance.
This commit is contained in:
Sandor Magyar 2022-10-17 17:32:08 -04:00
parent 0145223be1
commit a3c47cc682

View File

@ -20,6 +20,7 @@
#include <bsoncxx/view_or_value.hpp> #include <bsoncxx/view_or_value.hpp>
#include <mongocxx/client.hpp> #include <mongocxx/client.hpp>
#include <mongocxx/exception/logic_error.hpp>
#include <mongocxx/instance.hpp> #include <mongocxx/instance.hpp>
#include <mongocxx/uri.hpp> #include <mongocxx/uri.hpp>
@ -29,10 +30,23 @@ template<typename Mutex>
class mongo_sink : public base_sink<Mutex> class mongo_sink : public base_sink<Mutex>
{ {
public: public:
mongo_sink(const std::string &db_name, const std::string &collection_name, const std::string &uri = "mongodb://localhost:27017") mongo_sink(const std::string &db_name, const std::string &collection_name, const std::string &uri = "mongodb://localhost:27017",
bool create_instance = true)
{ {
try try
{ {
if (create_instance && !instance_)
{
try
{
instance_ = std::make_shared<mongocxx::instance>();
}
catch (const mongocxx::logic_error&)
{
// A MongoCXX instance already exists, so this object doesn't need to own it
instance_ = nullptr;
}
}
client_ = spdlog::details::make_unique<mongocxx::client>(mongocxx::uri{uri}); client_ = spdlog::details::make_unique<mongocxx::client>(mongocxx::uri{uri});
db_name_ = db_name; db_name_ = db_name;
coll_name_ = collection_name; coll_name_ = collection_name;
@ -68,13 +82,13 @@ protected:
void flush_() override {} void flush_() override {}
private: private:
static mongocxx::instance instance_; static std::shared_ptr<mongocxx::instance> instance_;
std::string db_name_; std::string db_name_;
std::string coll_name_; std::string coll_name_;
std::unique_ptr<mongocxx::client> client_ = nullptr; std::unique_ptr<mongocxx::client> client_ = nullptr;
}; };
template<> template<>
mongocxx::instance mongo_sink<std::mutex>::instance_{}; std::shared_ptr<mongocxx::instance> mongo_sink<std::mutex>::instance_{};
#include "spdlog/details/null_mutex.h" #include "spdlog/details/null_mutex.h"
#include <mutex> #include <mutex>