29 std::lock_guard
lock(_queueMutex);
30 if (_state != State::Stopped)
36 _state = State::Running;
38 _worker = std::thread([
this] { WorkerMain(); });
58 std::lock_guard
lock(_queueMutex);
59 if (_state != State::Running)
63 _state = State::Stopping;
64 _stopDeadline = std::chrono::steady_clock::now() +
stopDeadline;
66 _queueCv.notify_all();
70 std::lock_guard
lock(_queueMutex);
71 _state = State::Stopped;
78void Database::Enqueue(Job
job)
82 std::lock_guard
lock(_queueMutex);
83 if (_state != State::Running)
85 refused =
"database not running";
89 refused =
"the job queue is full";
93 _queue.push_back(std::move(
job));
99 _queueCv.notify_one();
107void Database::WorkerMain()
109 while (std::optional<Job>
job = TakeJob())
116std::optional<Database::Job> Database::TakeJob()
118 std::unique_lock
lock(_queueMutex);
119 _queueCv.wait(
lock, [
this] {
return !_queue.empty() || _state == State::Stopping; });
122 const bool pastDeadline = _state == State::Stopping && std::chrono::steady_clock::now() >= _stopDeadline;
127 Log::Warn(
"db: dropping queued '{}' - shutdown stop deadline reached.",
dropped.Name);
137 Job
job = std::move(_queue.front());
142void Database::RunJob(Job&
job)
146 Log::Error(
"db: '{}' failed - no database connection.",
job.Name);
153 job.Run(_connection);
155 catch (
const std::exception&
e)
163bool Database::EnsureOpen()
169 const auto now = std::chrono::steady_clock::now();
178 _connected.store(
true, std::memory_order_relaxed);
181 catch (
const std::exception&)
184 Log::Error(
"Database connection failed - check host/port/credentials.");
191void Database::DropConnection()
193 _connection.emplace<std::monostate>();
194 _connected.store(
false, std::memory_order_relaxed);
Result< ResultOf< Fn > > Run(std::string name, Fn fn)
bool Connect(const DatabaseConfig &config)
void Disconnect(std::chrono::milliseconds stopDeadline=std::chrono::seconds(5))
void DispatchCompletions()
Subscription EveryFrame(std::function< void()> callback)
void Error(std::format_string< Args... > fmt, Args &&... args)
void Warn(std::format_string< Args... > fmt, Args &&... args)
bool IsOpen(const AnyConnection &connection)
static std::string ReadFile(const std::filesystem::path &path)
static constexpr size_t MaxQueuedJobs
Result< Driver > CheckConfig(const DatabaseConfig &config)
std::expected< T, Error > Result
static constexpr auto ReconnectBackoff
void OpenConnection(AnyConnection &connection, Driver driver, const DatabaseConfig &config)
Connection parameters for every supported backend.
static Error Failed(std::string detail)
static Error NotReady(std::string detail)