From ef07168f71db21df4be34ec7a9c9d47c5a8128b6 Mon Sep 17 00:00:00 2001 From: Michael Davis Date: Wed, 11 Sep 2024 15:44:18 -0400 Subject: [PATCH] Use `erlang:whereis/1` for checking if a store is running MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A store's process uses its `StoreId` as its registered name. This is a public interface of Ra so we can depend on it. Reading from key metrics counters is already very fast but switching to `whereis/1` eliminates basically all overhead of this function. When used heavily (for example in RabbitMQ while publishing and consuming rapidly) the CPU time spent on `is_store_running/1` disappears from the output of a perf recording and a flamegraph. Co-authored-by: Jean-Sébastien Pédron --- src/khepri_cluster.erl | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/khepri_cluster.erl b/src/khepri_cluster.erl index 22682eb8..1b8768d7 100644 --- a/src/khepri_cluster.erl +++ b/src/khepri_cluster.erl @@ -1576,11 +1576,12 @@ get_store_ids() -> %% @doc Indicates if `StoreId' is running or not. is_store_running(StoreId) -> - ThisNode = node(), - RaServer = khepri_cluster:node_to_member(StoreId, ThisNode), - Timeout = khepri_app:get_default_timeout(), - KeyMetrics = ra:key_metrics(RaServer, Timeout), - Runs = maps:get(state, KeyMetrics) =/= noproc, + %% FIXME: Ra has no API to know if a Ra server is running or not. We could + %% use a public API such as `ra:key_metrics/2', but unfortunately, it is + %% not as efficient as querying the process directly. Therefore, we bypass + %% Ra and rely on the fact that the server ID is internally a registered + %% process name and resolve it to determine if it is running. + Runs = erlang:whereis(StoreId) =/= undefined, %% We know the real state of the Ra server. In the case the Ra server %% stopped behind the back of Khepri, we update the cached list of running