From d68f066faec6a98f3e268b8107e71e7626d48577 Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Mon, 19 Aug 2019 09:53:22 -0700 Subject: [PATCH] Try to use the new persistent term module instead of ETS in lager_config (#491) --- rebar.config.script | 16 +++++++- src/lager_app.erl | 3 +- src/lager_config.erl | 95 +++++++++++++++++++++++++++++++++----------- 3 files changed, 88 insertions(+), 26 deletions(-) diff --git a/rebar.config.script b/rebar.config.script index cefdea2..ac8ea1f 100644 --- a/rebar.config.script +++ b/rebar.config.script @@ -1,10 +1,22 @@ + +ExistingErlOpts = proplists:get_value(erl_opts, CONFIG, []), + +CONFIG1 = case code:which(persistent_term) of + preloaded -> + lists:keyreplace(erl_opts, 1, CONFIG, {erl_opts, [{d, 'HAVE_PERSISTENT_TERM'}|ExistingErlOpts]}); + non_existing -> + CONFIG + end, + + + case erlang:function_exported(rebar3, main, 1) of true -> % rebar3 - CONFIG; + CONFIG1; false -> % rebar 2.x or older %% Rebuild deps, possibly including those that have been moved to %% profiles [{deps, [ {goldrush, ".*", {git, "https://github.com/DeadZen/goldrush.git", {tag, "0.1.9"}}} - ]} | lists:keydelete(deps, 1, CONFIG)] + ]} | lists:keydelete(deps, 1, CONFIG1)] end. diff --git a/src/lager_app.erl b/src/lager_app.erl index 82c0139..be59289 100644 --- a/src/lager_app.erl +++ b/src/lager_app.erl @@ -273,7 +273,8 @@ boot_sink(Sink, false) -> stop(Handlers) -> lists:foreach(fun(Handler) -> error_logger:add_report_handler(Handler) - end, Handlers). + end, Handlers), + lager_config:cleanup(). expand_handlers([]) -> []; diff --git a/src/lager_config.erl b/src/lager_config.erl index 253894f..646ab8a 100644 --- a/src/lager_config.erl +++ b/src/lager_config.erl @@ -21,7 +21,7 @@ -include("lager.hrl"). -export([new/0, new_sink/1, get/1, get/2, set/2, - global_get/1, global_get/2, global_set/2]). + global_get/1, global_get/2, global_set/2, cleanup/0]). -define(TBL, lager_config). -define(GLOBAL, '_global'). @@ -32,24 +32,17 @@ %% {{lager_event, loglevel}, Value} instead of {loglevel, Value} new() -> - %% set up the ETS configuration table - _ = try ets:new(?TBL, [named_table, public, set, {keypos, 1}, {read_concurrency, true}]) of - _Result -> - ok - catch - error:badarg -> - ?INT_LOG(warning, "Table ~p already exists", [?TBL]) - end, + init(), new_sink(?DEFAULT_SINK), %% Need to be able to find the `lager_handler_watcher' for all handlers - ets:insert_new(?TBL, {{?GLOBAL, handlers}, []}), + insert_new({?GLOBAL, handlers}, []), ok. new_sink(Sink) -> %% use insert_new here so that if we're in an appup we don't mess anything up %% %% until lager is completely started, allow all messages to go through - ets:insert_new(?TBL, {{Sink, loglevel}, {element(2, lager_util:config_to_mask(debug)), []}}). + insert_new({Sink, loglevel}, {element(2, lager_util:config_to_mask(debug)), []}). global_get(Key) -> global_get(Key, undefined). @@ -67,21 +60,77 @@ get(Key) -> get({?DEFAULT_SINK, Key}, undefined). get({Sink, Key}, Default) -> - try - case ets:lookup(?TBL, {Sink, Key}) of - [] -> - Default; - [{{Sink, Key}, Res}] -> - Res - end - catch - _:_ -> - Default - end; + lookup({Sink, Key}, Default); get(Key, Default) -> get({?DEFAULT_SINK, Key}, Default). set({Sink, Key}, Value) -> - ets:insert(?TBL, {{Sink, Key}, Value}); + insert({Sink, Key}, Value); set(Key, Value) -> set({?DEFAULT_SINK, Key}, Value). + +%% check if we can use persistent_term for config +%% persistent term was added in OTP 21.2 but we can't +%% check minor versions with macros so we're stuck waiting +%% for OTP 22 +-ifdef(HAVE_PERSISTENT_TERM). +init() -> + ok. + +insert(Key, Value) -> + persistent_term:put({?TBL, Key}, Value). + +insert_new(Key, Value) -> + try persistent_term:get({?TBL, Key}) of + _Value -> + false + catch error:badarg -> + insert(Key, Value), + true + end. + +lookup(Key, Default) -> + try persistent_term:get({?TBL, Key}) of + Value -> Value + catch + error:badarg -> + Default + end. + +cleanup() -> + [ persistent_term:erase(K) || {{?TBL, _} = K, _} <- persistent_term:get() ]. + +-else. + +init() -> + %% set up the ETS configuration table + _ = try ets:new(?TBL, [named_table, public, set, {keypos, 1}, {read_concurrency, true}]) of + _Result -> + ok + catch + error:badarg -> + ?INT_LOG(warning, "Table ~p already exists", [?TBL]) + end. + +insert(Key, Value) -> + ets:insert(?TBL, {Key, Value}). + +insert_new(Key, Value) -> + ets:insert_new(?TBL, {Key, Value}). + +lookup(Key, Default) -> + try + case ets:lookup(?TBL, Key) of + [] -> + Default; + [{Key, Res}] -> + Res + end + catch + _:_ -> + Default + end. + +cleanup() -> ok. +-endif. +