Skip to content

Commit df19134

Browse files
authored
Merge pull request #349 from rabbitmq/optimize-effective-machine-version-query
khepri_machine: Cache effective machine version for faster queries
2 parents 7183339 + aeba63d commit df19134

1 file changed

Lines changed: 58 additions & 18 deletions

File tree

src/khepri_machine.erl

Lines changed: 58 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1223,7 +1223,8 @@ get_timeout(_) -> khepri_app:get_default_timeout().
12231223
%%
12241224
%% @private
12251225

1226-
clear_cache(_StoreId) ->
1226+
clear_cache(StoreId) ->
1227+
clear_cached_effective_machine_version(StoreId),
12271228
ok.
12281229

12291230
-spec sending_sync_command_locally(StoreId) -> ok when
@@ -1311,6 +1312,9 @@ init(Params) ->
13111312
%% state format.
13121313
State = khepri_machine_v0:init(Params),
13131314

1315+
#config{store_id = StoreId} = get_config(State),
1316+
cache_effective_machine_version(StoreId, 0),
1317+
13141318
%% Create initial "schema" if provided.
13151319
Commands = maps:get(commands, Params, []),
13161320
State3 = lists:foldl(
@@ -1700,6 +1704,12 @@ apply(
17001704
apply(Meta, {machine_version, OldMacVer, NewMacVer}, OldState) ->
17011705
NewState = convert_state(OldState, OldMacVer, NewMacVer),
17021706
Ret = {NewState, ok},
1707+
1708+
%% We cache the effective machine version for fast query from any
1709+
%% processes. This is useful because this machine version is used to
1710+
%% determine what a user of Khepri can or cannot do.
1711+
#config{store_id = StoreId} = get_config(NewState),
1712+
cache_effective_machine_version(StoreId, NewMacVer),
17031713
post_apply(Ret, Meta);
17041714
apply(#{machine_version := MacVer} = Meta, UnknownCommand, State) ->
17051715
Error = ?khepri_exception(
@@ -1926,32 +1936,62 @@ which_module(2) -> ?MODULE;
19261936
which_module(1) -> ?MODULE;
19271937
which_module(0) -> ?MODULE.
19281938

1939+
-define(
1940+
PT_EFFECTIVE_MACVER(StoreId),
1941+
{khepri, effective_machine_version, StoreId}).
1942+
19291943
-spec effective_version(StoreId) -> Ret when
19301944
StoreId :: khepri:store_id(),
19311945
Ret :: khepri:ok(EffectiveMacVer) | khepri:error(),
19321946
EffectiveMacVer :: ra_machine:version().
19331947
%% @doc Returns the effective state machine version of the local Ra server.
1948+
%%
1949+
%% The effective machine version is queried from a cached value, not from the
1950+
%% actual Ra server, to be more efficient.
19341951

19351952
effective_version(StoreId) when ?IS_KHEPRI_STORE_ID(StoreId) ->
1936-
ThisNode = node(),
1937-
RaServer = khepri_cluster:node_to_member(StoreId, ThisNode),
1938-
case ra_counters:counters(RaServer, [effective_machine_version]) of
1939-
#{effective_machine_version := EffectiveMacVer} ->
1940-
{ok, EffectiveMacVer};
1941-
_ ->
1942-
case ra:member_overview(RaServer) of
1943-
{ok, #{effective_machine_version := EffectiveMacVer}, _} ->
1944-
{ok, EffectiveMacVer};
1945-
{error, _} = Error ->
1946-
Reason = ?khepri_error(
1947-
effective_machine_version_not_defined,
1948-
#{store_id => StoreId,
1949-
ra_server => RaServer,
1950-
error => Error}),
1951-
{error, Reason}
1952-
end
1953+
Key = ?PT_EFFECTIVE_MACVER(StoreId),
1954+
try
1955+
EffectiveMacVer = persistent_term:get(Key),
1956+
{ok, EffectiveMacVer}
1957+
catch
1958+
error:badarg ->
1959+
ThisNode = node(),
1960+
RaServer = khepri_cluster:node_to_member(StoreId, ThisNode),
1961+
Reason = ?khepri_error(
1962+
effective_machine_version_not_defined,
1963+
#{store_id => StoreId,
1964+
ra_server => RaServer}),
1965+
{error, Reason}
19531966
end.
19541967

1968+
-spec cache_effective_machine_version(StoreId, EffectiveMacVer) -> ok when
1969+
StoreId :: khepri:store_id(),
1970+
EffectiveMacVer :: ra_machine:version().
1971+
%% @doc Caches effective machine version for fast query.
1972+
%%
1973+
%% The effective machine version is cached whenever the machine is initialised
1974+
%% and upgraded.
1975+
%%
1976+
%% @private
1977+
1978+
cache_effective_machine_version(StoreId, EffectiveMacVer) ->
1979+
Key = ?PT_EFFECTIVE_MACVER(StoreId),
1980+
persistent_term:put(Key, EffectiveMacVer).
1981+
1982+
-spec clear_cached_effective_machine_version(StoreId) -> ok when
1983+
StoreId :: khepri:store_id().
1984+
%% @doc Clears the cached effective machine version.
1985+
%%
1986+
%% The cached effective machine version is cleared when the store is stopped.
1987+
%%
1988+
%% @private
1989+
1990+
clear_cached_effective_machine_version(StoreId) ->
1991+
Key = ?PT_EFFECTIVE_MACVER(StoreId),
1992+
_ = persistent_term:erase(Key),
1993+
ok.
1994+
19551995
-spec does_api_comply_with(Behaviour, MacVer | StoreId) -> DoesUse when
19561996
Behaviour :: khepri_machine:api_behaviour(),
19571997
MacVer :: ra_machine:version(),

0 commit comments

Comments
 (0)