reader_concurrency_semaphore: add stats to record reason for queueing permits

When diagnosing problems, knowing why permits were queued is very
valuable. Record the reason in a new stats, one for each reason a permit
can be queued.
This commit is contained in:
Botond Dénes
2023-03-14 12:15:22 -04:00
parent bb00405818
commit 7b701ac52e
2 changed files with 23 additions and 1 deletions

View File

@@ -1189,7 +1189,16 @@ future<> reader_concurrency_semaphore::do_wait_admission(reader_permit::impl& pe
_execution_loop_future.emplace(execution_loop());
}
const auto admit = can_admit_read(permit).decision;
static uint64_t stats::*stats_table[] = {
&stats::reads_admitted_immediately,
&stats::reads_queued_because_ready_list,
&stats::reads_queued_because_used_permits,
&stats::reads_queued_because_memory_resources,
&stats::reads_queued_because_count_resources
};
const auto [admit, why] = can_admit_read(permit);
++(_stats.*stats_table[static_cast<int>(why)]);
if (admit != can_admit::yes || !_wait_list.empty()) {
auto fut = enqueue_waiter(permit, wait_on::admission);
if (admit == can_admit::yes && !_wait_list.empty()) {
@@ -1200,6 +1209,7 @@ future<> reader_concurrency_semaphore::do_wait_admission(reader_permit::impl& pe
maybe_dump_reader_permit_diagnostics(*this, "semaphore could admit new reads yet there are waiters");
maybe_admit_waiters();
} else if (admit == can_admit::maybe) {
++_stats.reads_queued_with_eviction;
evict_readers_in_background();
}
return fut;

View File

@@ -96,6 +96,18 @@ public:
uint64_t reads_enqueued_for_admission = 0;
// Total number of reads enqueued to wait for memory.
uint64_t reads_enqueued_for_memory = 0;
// Total number of reads admitted immediately, without queueing
uint64_t reads_admitted_immediately = 0;
// Total number of reads enqueued because ready_list wasn't empty
uint64_t reads_queued_because_ready_list = 0;
// Total number of reads enqueued because there are used but unblocked permits
uint64_t reads_queued_because_used_permits = 0;
// Total number of reads enqueued because there weren't enough memory resources
uint64_t reads_queued_because_memory_resources = 0;
// Total number of reads enqueued because there weren't enough count resources
uint64_t reads_queued_because_count_resources = 0;
// Total number of reads enqueued to be maybe admitted after evicting some inactive reads
uint64_t reads_queued_with_eviction = 0;
// Total number of permits created so far.
uint64_t total_permits = 0;
// Current number of permits.