Attempt to set max concurrent connections manually

This commit is contained in:
Simon Quigley 2025-01-27 01:00:33 -06:00
parent b618bf0932
commit c97454e828

View File

@ -17,6 +17,7 @@
#include <atomic> #include <atomic>
#include <chrono> #include <chrono>
#include <condition_variable>
#include <mutex> #include <mutex>
#include <thread> #include <thread>
@ -26,8 +27,11 @@
#include <QString> #include <QString>
// get_thread_connection and init_database // get_thread_connection and init_database
constexpr int MAX_CONNECTIONS = 5;
static std::mutex connection_mutex_; static std::mutex connection_mutex_;
static std::condition_variable connection_cv_;
static std::atomic<unsigned int> thread_id_counter{1}; static std::atomic<unsigned int> thread_id_counter{1};
static int active_connections = 0;
static QString shared_database_path; static QString shared_database_path;
static int get_delay(int attempt) { static int get_delay(int attempt) {
@ -40,34 +44,54 @@ QSqlDatabase get_thread_connection() {
bool passed = false; bool passed = false;
int attempt = 0; int attempt = 0;
while (!passed) { while (!passed) {
std::lock_guard<std::mutex> lock(connection_mutex_); {
thread_local unsigned int thread_unique_id = thread_id_counter.fetch_add(1); std::unique_lock<std::mutex> lock(connection_mutex_);
connection_name = QString("CIConn_%1").arg(thread_unique_id); connection_cv_.wait(lock, [] { return active_connections < MAX_CONNECTIONS; });
active_connections++;
// Check if the connection already exists for this thread
attempt++;
if (QSqlDatabase::contains(connection_name)) {
QSqlDatabase db = QSqlDatabase::database(connection_name);
if (!db.isOpen()) {
if (!db.open()) {
std::string last_error_text = db.lastError().text().toStdString();
if (last_error_text.contains("unable to open database file")) {
std::this_thread::sleep_for(std::chrono::milliseconds(get_delay(attempt)));
continue;
}
throw std::runtime_error(std::format("Failed to open thread-specific database connection: {}", last_error_text));
}
}
return db;
} }
thread_db = QSqlDatabase::addDatabase("QSQLITE", connection_name); try {
thread_db.setDatabaseName(shared_database_path); thread_local unsigned int thread_unique_id = thread_id_counter.fetch_add(1);
connection_name = QString("CIConn_%1").arg(thread_unique_id);
if (!thread_db.open()) throw std::runtime_error("Failed to open new database connection for thread: " + thread_db.lastError().text().toStdString()); // Check if the connection already exists for this thread
passed = true; attempt++;
if (QSqlDatabase::contains(connection_name)) {
QSqlDatabase db = QSqlDatabase::database(connection_name);
if (!db.isOpen()) {
if (!db.open()) {
std::string last_error_text = db.lastError().text().toStdString();
if (last_error_text.contains("unable to open database file")) {
std::this_thread::sleep_for(std::chrono::milliseconds(get_delay(attempt)));
continue;
}
throw std::runtime_error(std::format("Failed to open thread-specific database connection: {}", last_error_text));
}
}
return db;
}
thread_db = QSqlDatabase::addDatabase("QSQLITE", connection_name);
thread_db.setDatabaseName(shared_database_path);
if (!thread_db.open()) throw std::runtime_error("Failed to open new database connection for thread: " + thread_db.lastError().text().toStdString());
passed = true;
} catch (...) {
{
std::lock_guard<std::mutex> lock(connection_mutex_);
active_connections--;
}
connection_cv_.notify_one();
throw;
}
} }
{
std::lock_guard<std::mutex> lock(connection_mutex_);
active_connections--;
}
connection_cv_.notify_one();
return thread_db; return thread_db;
} }