Events 确保在Erlang/OTP中切换gen_事件处理程序时处理事件

Events 确保在Erlang/OTP中切换gen_事件处理程序时处理事件,events,erlang,otp,Events,Erlang,Otp,假设我有多个版本的gen_事件处理程序并希望在程序运行时更改它们: -module(logger_all). -behaviour(gen_event). -export([init/1, handle_event/2, terminate/2]). init(_Args) -> {ok, []}. handle_event({Severity, ErrorMsg}, State) -> io:format("***~p*** ~p~n", [Severity, Er

假设我有多个版本的
gen_事件处理程序
并希望在程序运行时更改它们:

-module(logger_all).
-behaviour(gen_event).
-export([init/1, handle_event/2, terminate/2]).
init(_Args) ->
    {ok, []}.
handle_event({Severity, ErrorMsg}, State) ->
    io:format("***~p*** ~p~n", [Severity, ErrorMsg]),
    {ok, State}.
terminate(_Args, _State) ->
    ok.

-module(logger_errors_only).
-behaviour(gen_event).
-export([init/1, handle_event/2, terminate/2]).
init(_Args) ->
    {ok, []}.
handle_event({error, ErrorMsg}, State) ->
    io:format("***Error*** ~p~n", [ErrorMsg]),
    {ok, State}.
handle_event({_, ErrorMsg}, State) ->
    {ok, State}. %% ignore everything except errors
terminate(_Args, _State) ->
    ok.
显然,我可以通过删除一个处理程序并添加另一个处理程序来切换它们:

log_errors_only() -> 
    gen_event:delete_handler(error_man, logger_all, []),
    gen_event:add_handler(error_man, logger_errors_only, []).
但这就留下了一个种族条件的可能性;如果
error\u man
在错误的时间接收到事件,则不会记录该事件。或者,如果我更改操作顺序,它将被记录两次,这也是不可取的。我如何确保它被精确地处理过一次


对于这种情况,我可以只使用一个处理程序,并将日志记录级别保持为
状态,但假设这是不可接受的;gen_事件具有以下功能:

log_errors_only() ->
    gen_event:swap_handler(error_man,
                           {logger_all, swapped_out},
                           {logger_errors_only, []}).