From 55a4a9caa39fbf845dcabfeba1470744c096aec0 Mon Sep 17 00:00:00 2001
From: Michael Davis <mcarsondavis@gmail.com>
Date: Wed, 4 Sep 2024 16:10:44 -0400
Subject: [PATCH] Add `counter_label` field to Ra server config

This new field sets the `seshat:label()` when creating a new counter for
a server (via `ra_counters:new/3` and in turn `seshat:new/4`).

This also deprecates the `counter` field. Having the creator of a Ra
server pass a `counters:counter_ref()` is unergonomic because the caller
must know the `seshat:fields_spec()` with which the counter should be
created.

Also in this change we remove the call to `ra_counters:new/2` from
the `ra_server_proc:config_defaults()` helper. By calling that function
when creating a default, the server process registered a counter
(causing an insertion into an ETS table in seshat) for the server even
if the caller specified a `counter` in the config.
---
 src/ra_server.erl      |  3 +++
 src/ra_server_proc.erl | 25 +++++++++++++++----------
 2 files changed, 18 insertions(+), 10 deletions(-)

diff --git a/src/ra_server.erl b/src/ra_server.erl
index 6ae440ac..914396fe 100644
--- a/src/ra_server.erl
+++ b/src/ra_server.erl
@@ -206,7 +206,9 @@
                               await_condition_timeout => non_neg_integer(),
                               max_pipeline_count => non_neg_integer(),
                               ra_event_formatter => {module(), atom(), [term()]},
+                              %% Deprecated in favor of counter_label:
                               counter => counters:counters_ref(),
+                              counter_label => seshat:label(),
                               membership => ra_membership(),
                               system_config => ra_system:config(),
                               has_changed => boolean()
@@ -214,6 +216,7 @@
 
 -type mutable_config() :: #{cluster_name => ra_cluster_name(),
                             metrics_key => term(),
+                            counter_label => seshat:label(),
                             broadcast_time => non_neg_integer(), % ms
                             tick_timeout => non_neg_integer(), % ms
                             install_snap_rpc_timeout => non_neg_integer(), % ms
diff --git a/src/ra_server_proc.erl b/src/ra_server_proc.erl
index 94b605bf..8ae80433 100644
--- a/src/ra_server_proc.erl
+++ b/src/ra_server_proc.erl
@@ -303,8 +303,21 @@ do_init(#{id := Id,
     true = ets:insert(ra_state, {Key, init, unknown}),
     process_flag(trap_exit, true),
     Config = #{counter := Counter,
-               system_config := SysConf} = maps:merge(config_defaults(Id),
+               system_config := SysConf} = maps:merge(config_defaults(),
                                                       Config0),
+    Counter = case maps:find(counter, Config) of
+                  {ok, C} ->
+                      C;
+                  error ->
+                      case ra_counters:fetch(Id) of
+                          undefined ->
+                              Label = maps:get(counter_label, Config, Id),
+                              ra_counters:new(
+                                Id, {persistent_term, ?FIELDSPEC_KEY}, Label);
+                          C ->
+                              C
+                      end
+              end,
     MsgQData = maps:get(message_queue_data, SysConf, off_heap),
     MinBinVheapSize = maps:get(server_min_bin_vheap_size, SysConf,
                                ?MIN_BIN_VHEAP_SIZE),
@@ -1709,20 +1722,12 @@ gen_statem_safe_call(ServerId, Msg, Timeout) ->
 do_state_query(QueryName, #state{server_state = State}) ->
     ra_server:state_query(QueryName, State).
 
-config_defaults(ServerId) ->
-    Counter = case ra_counters:fetch(ServerId) of
-                  undefined ->
-                      ra_counters:new(ServerId,
-                                      {persistent_term, ?FIELDSPEC_KEY});
-                  C ->
-                      C
-              end,
+config_defaults() ->
     #{broadcast_time => ?DEFAULT_BROADCAST_TIME,
       tick_timeout => ?TICK_INTERVAL_MS,
       install_snap_rpc_timeout => ?INSTALL_SNAP_RPC_TIMEOUT,
       await_condition_timeout => ?DEFAULT_AWAIT_CONDITION_TIMEOUT,
       initial_members => [],
-      counter => Counter,
       system_config => ra_system:default_config()
      }.