extended statement_cache with message bus events
This commit is contained in:
@@ -16,14 +16,25 @@ public:
|
||||
std::chrono::milliseconds max_wait{250};
|
||||
};
|
||||
|
||||
struct execution_metrics {
|
||||
std::chrono::steady_clock::time_point lock_attempt_start;
|
||||
std::chrono::steady_clock::time_point lock_acquired{};
|
||||
std::chrono::steady_clock::time_point execution_start{};
|
||||
std::chrono::steady_clock::time_point execution_end{};
|
||||
size_t lock_attempts{0};
|
||||
};
|
||||
|
||||
explicit statement_cache_proxy(std::unique_ptr<statement_impl>&& stmt, connection_pool &pool, const size_t connection_id)
|
||||
: statement_proxy(std::move(stmt))
|
||||
, pool_(pool)
|
||||
, connection_id_(connection_id) {}
|
||||
|
||||
utils::result<size_t, utils::error> execute(interface::parameter_binder& bindings) override {
|
||||
auto result = try_with_retry([this, &bindings]() -> utils::result<size_t, utils::error> {
|
||||
execution_metrics metrics{std::chrono::steady_clock::now()};
|
||||
|
||||
auto result = try_with_retry([this, &bindings, &metrics]() -> utils::result<size_t, utils::error> {
|
||||
if (!try_lock()) {
|
||||
++metrics.lock_attempts;
|
||||
return utils::failure(utils::error{
|
||||
error_code::STATEMENT_LOCKED,
|
||||
"Failed to execute statement because it is already in use"
|
||||
@@ -45,8 +56,11 @@ public:
|
||||
}
|
||||
|
||||
utils::result<std::unique_ptr<query_result_impl>, utils::error> fetch(interface::parameter_binder& bindings) override {
|
||||
auto result = try_with_retry([this, &bindings]() -> utils::result<std::unique_ptr<query_result_impl>, utils::error> {
|
||||
execution_metrics metrics{std::chrono::steady_clock::now()};
|
||||
|
||||
auto result = try_with_retry([this, &bindings, &metrics]() -> utils::result<std::unique_ptr<query_result_impl>, utils::error> {
|
||||
if (!try_lock()) {
|
||||
++metrics.lock_attempts;
|
||||
return utils::failure(utils::error{
|
||||
error_code::STATEMENT_LOCKED,
|
||||
"Failed to execute statement because it is already in use"
|
||||
@@ -114,10 +128,11 @@ private:
|
||||
};
|
||||
|
||||
}
|
||||
statement_cache::statement_cache(connection_pool &pool, const size_t max_size)
|
||||
statement_cache::statement_cache(utils::message_bus &bus, connection_pool &pool, const size_t max_size)
|
||||
: max_size_(max_size)
|
||||
, pool_(pool)
|
||||
, dialect_(backend_provider::instance().connection_dialect(pool_.info().type)) {}
|
||||
, dialect_(backend_provider::instance().connection_dialect(pool_.info().type))
|
||||
, bus_(bus) {}
|
||||
|
||||
utils::result<statement, utils::error> statement_cache::acquire(const query_context& ctx) {
|
||||
std::unique_lock lock(mutex_);
|
||||
@@ -128,7 +143,7 @@ utils::result<statement, utils::error> statement_cache::acquire(const query_cont
|
||||
if (const auto it = cache_map_.find(key); it != cache_map_.end()) {
|
||||
usage_list_.splice(usage_list_.begin(), usage_list_, it->second.position);
|
||||
it->second.last_access = now;
|
||||
push(statement_cache_event::Type::Accessed, ctx.sql);
|
||||
bus_.publish<statement_accessed_event>({ctx.sql, std::chrono::steady_clock::now()});
|
||||
return utils::ok(it->second.stmt);
|
||||
}
|
||||
// Prepare a new statement
|
||||
@@ -149,7 +164,7 @@ utils::result<statement, utils::error> statement_cache::acquire(const query_cont
|
||||
const auto& key_to_remove = usage_list_.back();
|
||||
cache_map_.erase(key_to_remove);
|
||||
usage_list_.pop_back();
|
||||
push(statement_cache_event::Type::Evicted, ctx.sql);
|
||||
bus_.publish<statement_evicted_event>({ctx.sql, std::chrono::steady_clock::now()});
|
||||
}
|
||||
|
||||
usage_list_.push_front(key);
|
||||
@@ -160,7 +175,7 @@ utils::result<statement, utils::error> statement_cache::acquire(const query_cont
|
||||
std::chrono::steady_clock::now(),
|
||||
usage_list_.begin()}
|
||||
}).first;
|
||||
push(statement_cache_event::Type::Added, ctx.sql);
|
||||
bus_.publish<statement_added_event>({ctx.sql, std::chrono::steady_clock::now()});
|
||||
|
||||
return utils::ok(it->second.stmt);
|
||||
}
|
||||
@@ -176,18 +191,4 @@ bool statement_cache::empty() const {
|
||||
return cache_map_.empty();
|
||||
}
|
||||
|
||||
void statement_cache::subscribe(statement_cache_observer_interface &observer) {
|
||||
observers_.push_back(&observer);
|
||||
}
|
||||
|
||||
void statement_cache::push(statement_cache_event::Type type, const std::string &sql) const {
|
||||
using Clock = std::chrono::steady_clock;
|
||||
const auto ts = Clock::now();
|
||||
const statement_cache_event evt{type, sql, ts};
|
||||
for (auto& obs : observers_) {
|
||||
if (obs) {
|
||||
obs->on_event(evt);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user