|
|
@ -4,8 +4,10 @@ |
|
|
|
-compile({inline_size, 128}). |
|
|
|
|
|
|
|
-include_lib("kernel/include/logger.hrl"). |
|
|
|
-include("genGbh.hrl"). |
|
|
|
|
|
|
|
-import(maps, [iterator/1, next/1]). |
|
|
|
-import(gen_call, [gcall/3, gcall/4, greply/2, try_greply/2]). |
|
|
|
|
|
|
|
-export([ |
|
|
|
%% API for gen_emm |
|
|
@ -14,7 +16,13 @@ |
|
|
|
, stop/1, stop/3 |
|
|
|
, call/3, call/4 |
|
|
|
, send/3 |
|
|
|
, send_request/3, wait_response/2, receive_response/2, check_response/2 |
|
|
|
|
|
|
|
, send_request/3, send_request/5 |
|
|
|
, wait_response/2, receive_response/2, check_response/2 |
|
|
|
, wait_response/3, receive_response/3, check_response/3 |
|
|
|
, reqids_new/0, reqids_size/1 |
|
|
|
, reqids_add/3, reqids_to_list/1 |
|
|
|
|
|
|
|
, info_notify/2, call_notify/2 |
|
|
|
, add_epm/3, add_sup_epm/3, del_epm/3 |
|
|
|
, swap_epm/3, swap_sup_epm/3 |
|
|
@ -35,21 +43,11 @@ |
|
|
|
, wakeupFromHib/5 |
|
|
|
|
|
|
|
%% logger callback |
|
|
|
, format_log/1, format_log/2 |
|
|
|
, format_log/1, format_log/2, print_event/3 |
|
|
|
]). |
|
|
|
|
|
|
|
-define(STACKTRACE(), element(2, erlang:process_info(self(), current_stacktrace))). |
|
|
|
|
|
|
|
%% debug 调试相关宏定义 |
|
|
|
-define(NOT_DEBUG, []). |
|
|
|
-define(SYS_DEBUG(Debug, Name, Msg), |
|
|
|
case Debug of |
|
|
|
?NOT_DEBUG -> |
|
|
|
Debug; |
|
|
|
_ -> |
|
|
|
sys:handle_debug(Debug, fun print_event/3, Name, Msg) |
|
|
|
end). |
|
|
|
|
|
|
|
-type epmHandler() :: |
|
|
|
atom() | |
|
|
|
{atom(), term()}. |
|
|
@ -105,7 +103,9 @@ |
|
|
|
{'error', term()}. |
|
|
|
|
|
|
|
-type from() :: {To :: pid(), Tag :: term()}. |
|
|
|
-type requestId() :: term(). |
|
|
|
-type request_id() :: gen:request_id(). |
|
|
|
-type request_id_collection() :: gen:request_id_collection(). |
|
|
|
-type response_timeout() :: timeout() | {abs, integer()}. |
|
|
|
|
|
|
|
-record(epmHer, { |
|
|
|
epmId = undefined :: term(), |
|
|
@ -122,8 +122,8 @@ |
|
|
|
-callback handleEvent(Event :: term(), State :: term()) -> |
|
|
|
kpS | |
|
|
|
removeEpm | |
|
|
|
{ok, NewState :: term()} | |
|
|
|
{ok, NewState :: term(), hibernate} | |
|
|
|
{noreply, NewState :: term()} | |
|
|
|
{noreply, NewState :: term(), hibernate} | |
|
|
|
{swapEpm, NewState :: term(), Args1 :: term(), NewHandler :: epmHandler(), Args2 :: term()}. |
|
|
|
|
|
|
|
-callback handleCall(Request :: term(), State :: term()) -> |
|
|
@ -136,8 +136,8 @@ |
|
|
|
-callback handleInfo(Info :: term(), State :: term()) -> |
|
|
|
kpS | |
|
|
|
removeEpm | |
|
|
|
{ok, NewState :: term()} | |
|
|
|
{ok, NewState :: term(), hibernate} | |
|
|
|
{noreply, NewState :: term()} | |
|
|
|
{noreply, NewState :: term(), hibernate} | |
|
|
|
{swapEpm, NewState :: term(), Args1 :: term(), NewHandler :: epmHandler(), Args2 :: term()}. |
|
|
|
|
|
|
|
-callback terminate(Args :: terminateArgs(), State :: term()) -> |
|
|
@ -264,34 +264,186 @@ call(EpmSrv, EpmHandler, Query, Timeout) -> |
|
|
|
send(EpmSrv, EpmHandler, Msg) -> |
|
|
|
epmRequest(EpmSrv, {'$epm_info', EpmHandler, Msg}). |
|
|
|
|
|
|
|
-spec send_request(serverRef(), epmHandler(), term()) -> requestId(). |
|
|
|
send_request(EpmSrv, EpmHandler, Query) -> |
|
|
|
gen:send_request(EpmSrv, '$epm_call', {'$epmCall', EpmHandler, Query}). |
|
|
|
-spec send_request(EventMgrRef::serverRef, Handler::epmHandler(), Request::term()) -> |
|
|
|
ReqId::request_id(). |
|
|
|
send_request(M, Handler, Request) -> |
|
|
|
try |
|
|
|
gen:send_request(M, '$epm_call', {'$epmCall', Handler, Request}) |
|
|
|
catch |
|
|
|
error:badarg -> |
|
|
|
error(badarg, [M, Handler, Request]) |
|
|
|
end. |
|
|
|
|
|
|
|
-spec send_request(EventMgrRef::serverRef, |
|
|
|
Handler::epmHandler(), |
|
|
|
Request::term(), |
|
|
|
Label::term(), |
|
|
|
ReqIdCollection::request_id_collection()) -> |
|
|
|
NewReqIdCollection::request_id_collection(). |
|
|
|
send_request(M, Handler, Request, Label, ReqIdCol) -> |
|
|
|
try |
|
|
|
gen:send_request(M, '$epm_call', {'$epmCall', Handler, Request}, Label, ReqIdCol) |
|
|
|
catch |
|
|
|
error:badarg -> |
|
|
|
error(badarg, [M, Handler, Request, Label, ReqIdCol]) |
|
|
|
end. |
|
|
|
|
|
|
|
-spec wait_response(ReqId, WaitTime) -> Result when |
|
|
|
ReqId :: request_id(), |
|
|
|
WaitTime :: response_timeout(), |
|
|
|
Response :: {reply, Reply::term()} |
|
|
|
| {error, {Reason::term(), serverRef}}, |
|
|
|
Result :: Response | 'timeout'. |
|
|
|
|
|
|
|
-spec wait_response(RequestId :: requestId(), timeout()) -> {reply, Reply :: term()} | 'timeout' | {error, {Reason :: term(), serverRef()}}. |
|
|
|
wait_response(RequestId, Timeout) -> |
|
|
|
case gen:wait_response(RequestId, Timeout) of |
|
|
|
wait_response(ReqId, WaitTime) -> |
|
|
|
try gen:wait_response(ReqId, WaitTime) of |
|
|
|
{reply, {error, _} = Err} -> Err; |
|
|
|
Return -> Return |
|
|
|
catch |
|
|
|
error:badarg -> |
|
|
|
error(badarg, [ReqId, WaitTime]) |
|
|
|
end. |
|
|
|
|
|
|
|
-spec wait_response(ReqIdCollection, WaitTime, Delete) -> Result when |
|
|
|
ReqIdCollection :: request_id_collection(), |
|
|
|
WaitTime :: response_timeout(), |
|
|
|
Delete :: boolean(), |
|
|
|
Response :: {reply, Reply::term()} | |
|
|
|
{error, {Reason::term(), serverRef}}, |
|
|
|
Result :: {Response, |
|
|
|
Label::term(), |
|
|
|
NewReqIdCollection::request_id_collection()} | |
|
|
|
'no_request' | |
|
|
|
'timeout'. |
|
|
|
|
|
|
|
wait_response(ReqIdCol, WaitTime, Delete) -> |
|
|
|
try gen:wait_response(ReqIdCol, WaitTime, Delete) of |
|
|
|
{{reply, {error, _} = Err}, Label, NewReqIdCol} -> |
|
|
|
{Err, Label, NewReqIdCol}; |
|
|
|
Return -> |
|
|
|
Return |
|
|
|
catch |
|
|
|
error:badarg -> |
|
|
|
error(badarg, [ReqIdCol, WaitTime, Delete]) |
|
|
|
end. |
|
|
|
|
|
|
|
-spec receive_response(RequestId::requestId(), timeout()) -> {reply, Reply::term()} | 'timeout' | {error, {Reason::term(), serverRef()}}. |
|
|
|
receive_response(RequestId, Timeout) -> |
|
|
|
case gen:receive_response(RequestId, Timeout) of |
|
|
|
-spec receive_response(ReqId, Timeout) -> Result when |
|
|
|
ReqId :: request_id(), |
|
|
|
Timeout :: response_timeout(), |
|
|
|
Response :: {reply, Reply::term()} | |
|
|
|
{error, {Reason::term(), serverRef}}, |
|
|
|
Result :: Response | 'timeout'. |
|
|
|
|
|
|
|
receive_response(ReqId, Timeout) -> |
|
|
|
try gen:receive_response(ReqId, Timeout) of |
|
|
|
{reply, {error, _} = Err} -> Err; |
|
|
|
Return -> Return |
|
|
|
catch |
|
|
|
error:badarg -> |
|
|
|
error(badarg, [ReqId, Timeout]) |
|
|
|
end. |
|
|
|
|
|
|
|
-spec receive_response(ReqIdCollection, Timeout, Delete) -> Result when |
|
|
|
ReqIdCollection :: request_id_collection(), |
|
|
|
Timeout :: response_timeout(), |
|
|
|
Delete :: boolean(), |
|
|
|
Response :: {reply, Reply::term()} | |
|
|
|
{error, {Reason::term(), serverRef}}, |
|
|
|
Result :: {Response, |
|
|
|
Label::term(), |
|
|
|
NewReqIdCollection::request_id_collection()} | |
|
|
|
'no_request' | |
|
|
|
'timeout'. |
|
|
|
|
|
|
|
receive_response(ReqIdCol, Timeout, Delete) -> |
|
|
|
try gen:receive_response(ReqIdCol, Timeout, Delete) of |
|
|
|
{{reply, {error, _} = Err}, Label, NewReqIdCol} -> |
|
|
|
{Err, Label, NewReqIdCol}; |
|
|
|
Return -> |
|
|
|
Return |
|
|
|
catch |
|
|
|
error:badarg -> |
|
|
|
error(badarg, [ReqIdCol, Timeout, Delete]) |
|
|
|
end. |
|
|
|
|
|
|
|
-spec check_response(Msg :: term(), RequestId :: requestId()) -> |
|
|
|
{reply, Reply :: term()} | 'no_reply' | {error, {Reason :: term(), serverRef()}}. |
|
|
|
check_response(Msg, RequestId) -> |
|
|
|
case gen:check_response(Msg, RequestId) of |
|
|
|
-spec check_response(Msg, ReqId) -> Result when |
|
|
|
Msg :: term(), |
|
|
|
ReqId :: request_id(), |
|
|
|
Response :: {reply, Reply::term()} | |
|
|
|
{error, {Reason::term(), serverRef}}, |
|
|
|
Result :: Response | 'no_reply'. |
|
|
|
|
|
|
|
check_response(Msg, ReqId) -> |
|
|
|
try gen:check_response(Msg, ReqId) of |
|
|
|
{reply, {error, _} = Err} -> Err; |
|
|
|
Return -> Return |
|
|
|
catch |
|
|
|
error:badarg -> |
|
|
|
error(badarg, [Msg, ReqId]) |
|
|
|
end. |
|
|
|
|
|
|
|
-spec check_response(Msg, ReqIdCollection, Delete) -> Result when |
|
|
|
Msg :: term(), |
|
|
|
ReqIdCollection :: request_id_collection(), |
|
|
|
Delete :: boolean(), |
|
|
|
Response :: {reply, Reply::term()} | |
|
|
|
{error, {Reason::term(), serverRef}}, |
|
|
|
Result :: {Response, |
|
|
|
Label::term(), |
|
|
|
NewReqIdCollection::request_id_collection()} | |
|
|
|
'no_request' | |
|
|
|
'no_reply'. |
|
|
|
|
|
|
|
check_response(Msg, ReqIdCol, Delete) -> |
|
|
|
try gen:check_response(Msg, ReqIdCol, Delete) of |
|
|
|
{{reply, {error, _} = Err}, Label, NewReqIdCol} -> |
|
|
|
{Err, Label, NewReqIdCol}; |
|
|
|
Return -> |
|
|
|
Return |
|
|
|
catch |
|
|
|
error:badarg -> |
|
|
|
error(badarg, [Msg, ReqIdCol, Delete]) |
|
|
|
end. |
|
|
|
|
|
|
|
-spec reqids_new() -> |
|
|
|
NewReqIdCollection::request_id_collection(). |
|
|
|
|
|
|
|
reqids_new() -> |
|
|
|
gen:reqids_new(). |
|
|
|
|
|
|
|
-spec reqids_size(ReqIdCollection::request_id_collection()) -> |
|
|
|
non_neg_integer(). |
|
|
|
|
|
|
|
reqids_size(ReqIdCollection) -> |
|
|
|
try |
|
|
|
gen:reqids_size(ReqIdCollection) |
|
|
|
catch |
|
|
|
error:badarg -> error(badarg, [ReqIdCollection]) |
|
|
|
end. |
|
|
|
|
|
|
|
-spec reqids_add(ReqId::request_id(), Label::term(), |
|
|
|
ReqIdCollection::request_id_collection()) -> |
|
|
|
NewReqIdCollection::request_id_collection(). |
|
|
|
|
|
|
|
reqids_add(ReqId, Label, ReqIdCollection) -> |
|
|
|
try |
|
|
|
gen:reqids_add(ReqId, Label, ReqIdCollection) |
|
|
|
catch |
|
|
|
error:badarg -> error(badarg, [ReqId, Label, ReqIdCollection]) |
|
|
|
end. |
|
|
|
|
|
|
|
-spec reqids_to_list(ReqIdCollection::request_id_collection()) -> |
|
|
|
[{ReqId::request_id(), Label::term()}]. |
|
|
|
|
|
|
|
reqids_to_list(ReqIdCollection) -> |
|
|
|
try |
|
|
|
gen:reqids_to_list(ReqIdCollection) |
|
|
|
catch |
|
|
|
error:badarg -> error(badarg, [ReqIdCollection]) |
|
|
|
end. |
|
|
|
|
|
|
|
epmRpc(EpmSrv, Cmd) -> |
|
|
|
try gen:call(EpmSrv, '$epm_call', Cmd, infinity) of |
|
|
|
try gcall(EpmSrv, '$epm_call', Cmd, infinity) of |
|
|
|
{ok, Reply} -> |
|
|
|
Reply |
|
|
|
catch Class:Reason -> |
|
|
@ -299,7 +451,7 @@ epmRpc(EpmSrv, Cmd) -> |
|
|
|
end. |
|
|
|
|
|
|
|
epmRpc(EpmSrv, Cmd, Timeout) -> |
|
|
|
try
gen:call(EpmSrv, '$epm_call', Cmd, Timeout) of |
|
|
|
try gcall(EpmSrv, '$epm_call', Cmd, Timeout) of |
|
|
|
{ok, Reply} -> |
|
|
|
Reply |
|
|
|
catch Class:Reason -> |
|
|
@ -345,65 +497,65 @@ receiveIng(Parent, ServerName, HibernateAfterTimeout, EpmHers, Debug, IsHib) -> |
|
|
|
end. |
|
|
|
|
|
|
|
epmCallMsg(Parent, ServerName, HibernateAfterTimeout, EpmHers, Debug, From, Request) -> |
|
|
|
NewDebug = ?SYS_DEBUG(Debug, ServerName, {call, From, Request}), |
|
|
|
?SYS_DEBUG(Debug, ServerName, {call, From, Request}), |
|
|
|
case Request of |
|
|
|
'$which_handlers' -> |
|
|
|
reply(From, maps:keys(EpmHers)), |
|
|
|
receiveIng(Parent, ServerName, HibernateAfterTimeout, EpmHers, NewDebug, false); |
|
|
|
receiveIng(Parent, ServerName, HibernateAfterTimeout, EpmHers, Debug, false); |
|
|
|
{'$addEpm', EpmHandler, Args} -> |
|
|
|
{Reply, NewEpmHers, IsHib} = doAddEpm(EpmHers, EpmHandler, Args, undefined), |
|
|
|
reply(From, Reply), |
|
|
|
loopEntry(Parent, ServerName, HibernateAfterTimeout, NewEpmHers, NewDebug, IsHib); |
|
|
|
loopEntry(Parent, ServerName, HibernateAfterTimeout, NewEpmHers, Debug, IsHib); |
|
|
|
{'$addSupEpm', EpmHandler, Args, EpmSup} -> |
|
|
|
{Reply, NewEpmHers, IsHib} = doAddSupEpm(EpmHers, EpmHandler, Args, EpmSup), |
|
|
|
reply(From, Reply), |
|
|
|
loopEntry(Parent, ServerName, HibernateAfterTimeout, NewEpmHers, NewDebug, IsHib); |
|
|
|
loopEntry(Parent, ServerName, HibernateAfterTimeout, NewEpmHers, Debug, IsHib); |
|
|
|
{'$delEpm', EpmHandler, Args} -> |
|
|
|
{Reply, NewEpmHers} = doDelEpm(EpmHers, EpmHandler, Args), |
|
|
|
reply(From, Reply), |
|
|
|
receiveIng(Parent, ServerName, HibernateAfterTimeout, NewEpmHers, NewDebug, false); |
|
|
|
receiveIng(Parent, ServerName, HibernateAfterTimeout, NewEpmHers, Debug, false); |
|
|
|
{'$swapEpm', EpmId1, Args1, EpmId2, Args2} -> |
|
|
|
{Reply, NewEpmHers, IsHib} = doSwapEpm(EpmHers, EpmId1, Args1, EpmId2, Args2), |
|
|
|
reply(From, Reply), |
|
|
|
loopEntry(Parent, ServerName, HibernateAfterTimeout, NewEpmHers, NewDebug, IsHib); |
|
|
|
loopEntry(Parent, ServerName, HibernateAfterTimeout, NewEpmHers, Debug, IsHib); |
|
|
|
{'$swapSupEpm', EpmId1, Args1, EpmId2, Args2, SupPid} -> |
|
|
|
{Reply, NewEpmHers, IsHib} = doSwapSupEpm(EpmHers, EpmId1, Args1, EpmId2, Args2, SupPid), |
|
|
|
reply(From, Reply), |
|
|
|
loopEntry(Parent, ServerName, HibernateAfterTimeout, NewEpmHers, NewDebug, IsHib); |
|
|
|
loopEntry(Parent, ServerName, HibernateAfterTimeout, NewEpmHers, Debug, IsHib); |
|
|
|
{'$syncNotify', Event} -> |
|
|
|
{NewEpmHers, IsHib} = doNotify(EpmHers, handleEvent, Event, false), |
|
|
|
reply(From, ok), |
|
|
|
loopEntry(Parent, ServerName, HibernateAfterTimeout, NewEpmHers, NewDebug, IsHib); |
|
|
|
loopEntry(Parent, ServerName, HibernateAfterTimeout, NewEpmHers, Debug, IsHib); |
|
|
|
{'$epmCall', EpmHandler, Query} -> |
|
|
|
case doEpmHandle(EpmHers, EpmHandler, handleCall, Query, From) of |
|
|
|
{NewEpmHers, IsHib} -> |
|
|
|
loopEntry(Parent, ServerName, HibernateAfterTimeout, NewEpmHers, NewDebug, IsHib); |
|
|
|
loopEntry(Parent, ServerName, HibernateAfterTimeout, NewEpmHers, Debug, IsHib); |
|
|
|
NewEpmHers -> |
|
|
|
loopEntry(Parent, ServerName, HibernateAfterTimeout, NewEpmHers, NewDebug, false) |
|
|
|
loopEntry(Parent, ServerName, HibernateAfterTimeout, NewEpmHers, Debug, false) |
|
|
|
end |
|
|
|
end. |
|
|
|
|
|
|
|
epmInfoMsg(Parent, ServerName, HibernateAfterTimeout, EpmHers, Debug, CmdOrEmpHandler, Event) -> |
|
|
|
NewDebug = ?SYS_DEBUG(Debug, ServerName, {info, CmdOrEmpHandler, Event}), |
|
|
|
?SYS_DEBUG(Debug, ServerName, {info, CmdOrEmpHandler, Event}), |
|
|
|
case CmdOrEmpHandler of |
|
|
|
'$infoNotify' -> |
|
|
|
{NewEpmHers, IsHib} = doNotify(EpmHers, handleEvent, Event, false), |
|
|
|
loopEntry(Parent, ServerName, HibernateAfterTimeout, NewEpmHers, NewDebug, IsHib); |
|
|
|
loopEntry(Parent, ServerName, HibernateAfterTimeout, NewEpmHers, Debug, IsHib); |
|
|
|
EpmHandler -> |
|
|
|
case doEpmHandle(EpmHers, EpmHandler, handleInfo, Event, false) of |
|
|
|
{NewEpmHers, IsHib} -> |
|
|
|
loopEntry(Parent, ServerName, HibernateAfterTimeout, NewEpmHers, NewDebug, IsHib); |
|
|
|
loopEntry(Parent, ServerName, HibernateAfterTimeout, NewEpmHers, Debug, IsHib); |
|
|
|
NewEpmHers -> |
|
|
|
loopEntry(Parent, ServerName, HibernateAfterTimeout, NewEpmHers, NewDebug, false) |
|
|
|
loopEntry(Parent, ServerName, HibernateAfterTimeout, NewEpmHers, Debug, false) |
|
|
|
end |
|
|
|
end. |
|
|
|
|
|
|
|
handleMsg(Parent, ServerName, HibernateAfterTimeout, EpmHers, Debug, Msg) -> |
|
|
|
NewDebug = ?SYS_DEBUG(Debug, ServerName, {in, Msg}), |
|
|
|
?SYS_DEBUG(Debug, ServerName, {in, Msg}), |
|
|
|
case Msg of |
|
|
|
{'EXIT', From, Reason} -> |
|
|
|
NewEpmHers = epmStopOne(From, EpmHers, Reason), |
|
|
|
receiveIng(Parent, ServerName, HibernateAfterTimeout, NewEpmHers, NewDebug, false); |
|
|
|
receiveIng(Parent, ServerName, HibernateAfterTimeout, NewEpmHers, Debug, false); |
|
|
|
{_From, Tag, stop} -> |
|
|
|
try terminate_server(normal, Parent, ServerName, EpmHers) |
|
|
|
after |
|
|
@ -411,13 +563,13 @@ handleMsg(Parent, ServerName, HibernateAfterTimeout, EpmHers, Debug, Msg) -> |
|
|
|
end; |
|
|
|
{_From, Tag, get_modules} -> |
|
|
|
reply(Tag, get_modules(EpmHers)), |
|
|
|
receiveIng(Parent, ServerName, HibernateAfterTimeout, EpmHers, NewDebug, false); |
|
|
|
receiveIng(Parent, ServerName, HibernateAfterTimeout, EpmHers, Debug, false); |
|
|
|
{_From, Tag, which_handlers} -> |
|
|
|
reply(Tag, maps:keys(EpmHers)), |
|
|
|
receiveIng(Parent, ServerName, HibernateAfterTimeout, EpmHers, NewDebug, false); |
|
|
|
receiveIng(Parent, ServerName, HibernateAfterTimeout, EpmHers, Debug, false); |
|
|
|
_ -> |
|
|
|
{NewEpmHers, IsHib} = doNotify(EpmHers, handleInfo, Msg, false), |
|
|
|
loopEntry(Parent, ServerName, HibernateAfterTimeout, NewEpmHers, NewDebug, IsHib) |
|
|
|
loopEntry(Parent, ServerName, HibernateAfterTimeout, NewEpmHers, Debug, IsHib) |
|
|
|
end. |
|
|
|
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
@ -503,10 +655,10 @@ doSwapSupEpm(EpmHers, EpmId1, Args1, EpmMId, Args2, EpmSup) -> |
|
|
|
end. |
|
|
|
|
|
|
|
doNotify(EpmHers, Func, Event, _Form) -> |
|
|
|
allNotify(maps:iterator(EpmHers), Func, Event, false, EpmHers, false). |
|
|
|
allNotify(iterator(EpmHers), Func, Event, false, EpmHers, false). |
|
|
|
|
|
|
|
allNotify(Iterator, Func, Event, From, TemEpmHers, IsHib) -> |
|
|
|
case maps:next(Iterator) of |
|
|
|
case next(Iterator) of |
|
|
|
{K, _V, NextIterator} -> |
|
|
|
case doEpmHandle(TemEpmHers, K, Func, Event, From) of |
|
|
|
{NewEpmHers, NewIsHib} -> |
|
|
@ -527,12 +679,12 @@ doEpmHandle(EpmHers, EpmId, Func, Event, From) -> |
|
|
|
catch |
|
|
|
throw:Ret -> |
|
|
|
handleEpmCR(Ret, EpmHers, EpmId, EpmHer, Event, From); |
|
|
|
C:R:S -> |
|
|
|
epmTerminate(EpmHer, {error, {C, R, S}}, Event, crash), |
|
|
|
Class:Reason:Strace -> |
|
|
|
epmTerminate(EpmHer, {error, {Class, Reason, Strace}}, Event, crash), |
|
|
|
maps:remove(EpmId, EpmHers) |
|
|
|
end; |
|
|
|
_ -> |
|
|
|
try_reply(From, {error, bad_module}), |
|
|
|
try_greply(From, {error, bad_module}), |
|
|
|
EpmHers |
|
|
|
end. |
|
|
|
|
|
|
@ -550,10 +702,10 @@ handleEpmCR(Result, EpmHers, EpmId, EpmHer, Event, From) -> |
|
|
|
case Result of |
|
|
|
kpS -> |
|
|
|
EpmHers; |
|
|
|
{ok, NewEpmS} -> |
|
|
|
{noreply, NewEpmS} -> |
|
|
|
MewEpmHer = setelement(#epmHer.epmS, EpmHer, NewEpmS), |
|
|
|
EpmHers#{EpmId := MewEpmHer}; |
|
|
|
{ok, NewEpmS, hibernate} -> |
|
|
|
{noreply, NewEpmS, hibernate} -> |
|
|
|
MewEpmHer = setelement(#epmHer.epmS, EpmHer, NewEpmS), |
|
|
|
{EpmHers#{EpmId := MewEpmHer}, true}; |
|
|
|
{swapEpm, NewEpmS, Args1, EpmMId, Args2} -> |
|
|
@ -600,7 +752,7 @@ handleEpmCR(Result, EpmHers, EpmId, EpmHer, Event, From) -> |
|
|
|
MewEpmHer = setelement(#epmHer.epmS, EpmHer, NewEpmS), |
|
|
|
{EpmHers#{EpmId := MewEpmHer}, true}; |
|
|
|
Other -> |
|
|
|
epmTerminate(EpmHer, {error, Other}, Event, crash), |
|
|
|
epmTerminate(EpmHer, {error, {bad_ret, Other}}, Event, crash), |
|
|
|
maps:remove(EpmId, EpmHers) |
|
|
|
end. |
|
|
|
|
|
|
@ -636,14 +788,14 @@ report_error(#epmHer{epmId = EpmId, epmM = EpmM}, Reason, State, LastIn) -> |
|
|
|
#{ |
|
|
|
domain => [otp], |
|
|
|
report_cb => fun gen_emm:format_log/2, |
|
|
|
error_logger => #{tag => error, report_cb => fun gen_event:format_log/1} |
|
|
|
error_logger => #{tag => error, report_cb => fun gen_emm:format_log/1} |
|
|
|
}). |
|
|
|
|
|
|
|
epmStopAll(EpmHers) -> |
|
|
|
forStopAll(maps:iterator(EpmHers)). |
|
|
|
forStopAll(iterator(EpmHers)). |
|
|
|
|
|
|
|
forStopAll(Iterator) -> |
|
|
|
case maps:next(Iterator) of |
|
|
|
case next(Iterator) of |
|
|
|
{_K, V, NextIterator} -> |
|
|
|
epmTerminate(V, stop, stop, shutdown), |
|
|
|
case element(#epmHer.epmSup, V) of |
|
|
@ -658,10 +810,10 @@ forStopAll(Iterator) -> |
|
|
|
end. |
|
|
|
|
|
|
|
epmStopOne(ExitEmpSup, EpmHers, Reason) -> |
|
|
|
forStopOne(maps:iterator(EpmHers), ExitEmpSup, Reason, EpmHers). |
|
|
|
forStopOne(iterator(EpmHers), ExitEmpSup, Reason, EpmHers). |
|
|
|
|
|
|
|
forStopOne(Iterator, ExitEmpSup, Reason, TemEpmHers) -> |
|
|
|
case maps:next(Iterator) of |
|
|
|
case next(Iterator) of |
|
|
|
{K, V, NextIterator} -> |
|
|
|
case element(#epmHer.epmSup, V) =:= ExitEmpSup of |
|
|
|
true -> |
|
|
@ -685,28 +837,10 @@ epmTerminate(#epmHer{epmM = EpmM, epmS = State} = EpmHer, Args, LastIn, Reason) |
|
|
|
ok |
|
|
|
end. |
|
|
|
|
|
|
|
-compile({inline, [reply/2]}). |
|
|
|
-spec reply(From :: from(), Reply :: term()) -> ok. |
|
|
|
reply({_To, [alias|Alias] = Tag}, Reply) -> |
|
|
|
Alias ! {Tag, Reply}, |
|
|
|
ok; |
|
|
|
reply({To, Ref}, Msg) -> |
|
|
|
try To ! {Ref, Msg}, |
|
|
|
ok |
|
|
|
catch _:_ -> |
|
|
|
ok |
|
|
|
end. |
|
|
|
|
|
|
|
try_reply(false, _Msg) -> |
|
|
|
ignore; |
|
|
|
try_reply({_To, [alias|Alias] = Tag}, Reply) -> |
|
|
|
Alias ! {Tag, Reply}, |
|
|
|
ok; |
|
|
|
try_reply({To, Ref}, Msg) -> |
|
|
|
try To ! {Ref, Msg}, |
|
|
|
ok |
|
|
|
catch _:_ -> |
|
|
|
ok |
|
|
|
end. |
|
|
|
reply(From, Reply) -> |
|
|
|
greply(From, Reply). |
|
|
|
|
|
|
|
terminate_server(Reason, _Parent, _ServerName, EpmHers) -> |
|
|
|
epmStopAll(EpmHers), |
|
|
@ -727,11 +861,11 @@ system_terminate(Reason, Parent, _Debug, {ServerName, _HibernateAfterTimeout, Ep |
|
|
|
%% which module should be changed. |
|
|
|
%%----------------------------------------------------------------- |
|
|
|
system_code_change({ServerName, HibernateAfterTimeout, EpmHers, IsHib}, Module, OldVsn, Extra) -> |
|
|
|
NewEpmHers = forCodeChange(maps:iterator(EpmHers), Module, OldVsn, Extra, EpmHers), |
|
|
|
NewEpmHers = forCodeChange(iterator(EpmHers), Module, OldVsn, Extra, EpmHers), |
|
|
|
{ok, {ServerName, HibernateAfterTimeout, NewEpmHers, IsHib}}. |
|
|
|
|
|
|
|
forCodeChange(Iterator, CModule, OldVsn, Extra, TemEpmHers) -> |
|
|
|
case maps:next(Iterator) of |
|
|
|
case next(Iterator) of |
|
|
|
{K, #epmHer{epmM = Module, epmS = EpmS} = V, NextIterator} when Module =:= CModule -> |
|
|
|
{ok, NewEpmS} = Module:code_change(OldVsn, EpmS, Extra), |
|
|
|
forCodeChange(NextIterator, CModule, OldVsn, Extra, TemEpmHers#{K := V#epmHer{epmS = NewEpmS}}); |
|
|
@ -742,10 +876,10 @@ forCodeChange(Iterator, CModule, OldVsn, Extra, TemEpmHers) -> |
|
|
|
end. |
|
|
|
|
|
|
|
system_get_state({_ServerName, _HibernateAfterTimeout, EpmHers, _Hib}) -> |
|
|
|
{ok, forGetState(maps:iterator(EpmHers), [])}. |
|
|
|
{ok, forGetState(iterator(EpmHers), [])}. |
|
|
|
|
|
|
|
forGetState(Iterator, Acc) -> |
|
|
|
case maps:next(Iterator) of |
|
|
|
case next(Iterator) of |
|
|
|
{_K, #epmHer{epmId = EpmId, epmM = Module, epmS = EpmS}, NextIterator} -> |
|
|
|
forGetState(NextIterator, [{Module, EpmId, EpmS} | Acc]); |
|
|
|
_ -> |
|
|
@ -753,11 +887,11 @@ forGetState(Iterator, Acc) -> |
|
|
|
end. |
|
|
|
|
|
|
|
system_replace_state(StateFun, {ServerName, HibernateAfterTimeout, EpmHers, IsHib}) -> |
|
|
|
{NewEpmHers, NStates} = forReplaceState(maps:iterator(EpmHers), StateFun, EpmHers, []), |
|
|
|
{NewEpmHers, NStates} = forReplaceState(iterator(EpmHers), StateFun, EpmHers, []), |
|
|
|
{ok, NStates, {ServerName, HibernateAfterTimeout, NewEpmHers, IsHib}}. |
|
|
|
|
|
|
|
forReplaceState(Iterator, StateFun, TemEpmHers, NStates) -> |
|
|
|
case maps:next(Iterator) of |
|
|
|
case next(Iterator) of |
|
|
|
{K, #epmHer{epmId = EpmId, epmM = Module, epmS = EpmS} = V, NextIterator} -> |
|
|
|
NState = {_, _, NewEpmS} = StateFun({Module, EpmId, EpmS}), |
|
|
|
forReplaceState(NextIterator, StateFun, TemEpmHers#{K := V#epmHer{epmS = NewEpmS}}, [NState | NStates]); |
|
|
@ -798,7 +932,7 @@ format_log(Report) -> |
|
|
|
|
|
|
|
limit_report(Report, unlimited) -> |
|
|
|
Report; |
|
|
|
limit_report(#{label := {gen_event, terminate}, |
|
|
|
limit_report(#{label := {gen_emm, epm_terminate}, |
|
|
|
last_message := LastIn, |
|
|
|
state := State, |
|
|
|
reason := Reason} = Report, |
|
|
@ -807,9 +941,7 @@ limit_report(#{label := {gen_event, terminate}, |
|
|
|
last_message => io_lib:limit_term(LastIn, Depth), |
|
|
|
state => io_lib:limit_term(State, Depth), |
|
|
|
reason => io_lib:limit_term(Reason, Depth) |
|
|
|
}; |
|
|
|
limit_report(#{label := {gen_event, no_handle_info}, message := Msg} = Report, Depth) -> |
|
|
|
Report#{message => io_lib:limit_term(Msg, Depth)}. |
|
|
|
}. |
|
|
|
|
|
|
|
%% format_log/2 is the report callback for any Logger handler, except |
|
|
|
%% error_logger. |
|
|
@ -831,7 +963,7 @@ format_log(Report, FormatOpts0) -> |
|
|
|
{Format, Args} = format_log_single(Report, FormatOpts), |
|
|
|
io_lib:format(Format, Args, IoOpts). |
|
|
|
|
|
|
|
format_log_single(#{label := {gen_event, terminate}, |
|
|
|
format_log_single(#{label := {gen_emm, epm_terminate}, |
|
|
|
handler := Handler, |
|
|
|
name := SName, |
|
|
|
last_message := LastIn, |
|
|
@ -851,25 +983,9 @@ format_log_single(#{label := {gen_event, terminate}, |
|
|
|
[Handler, Depth, SName, Depth, Reason1, Depth, |
|
|
|
LastIn, Depth, State, Depth] |
|
|
|
end, |
|
|
|
{Format1, Args1}; |
|
|
|
format_log_single(#{label := {gen_event, no_handle_info}, |
|
|
|
module := Mod, |
|
|
|
message := Msg}, |
|
|
|
#{single_line := true, depth := Depth} = FormatOpts) -> |
|
|
|
P = p(FormatOpts), |
|
|
|
Format = lists:append(["Undefined handle_info in ", P, ". Unhandled message: ", P, "."]), |
|
|
|
Args = |
|
|
|
case Depth of |
|
|
|
unlimited -> |
|
|
|
[Mod, Msg]; |
|
|
|
_ -> |
|
|
|
[Mod, Depth, Msg, Depth] |
|
|
|
end, |
|
|
|
{Format, Args}; |
|
|
|
format_log_single(Report, FormatOpts) -> |
|
|
|
format_log_multi(Report, FormatOpts). |
|
|
|
{Format1, Args1}. |
|
|
|
|
|
|
|
format_log_multi(#{label := {gen_event, terminate}, |
|
|
|
format_log_multi(#{label := {gen_emm, epm_terminate}, |
|
|
|
handler := Handler, |
|
|
|
name := SName, |
|
|
|
last_message := LastIn, |
|
|
@ -879,7 +995,7 @@ format_log_multi(#{label := {gen_event, terminate}, |
|
|
|
Reason1 = fix_reason(Reason), |
|
|
|
P = p(FormatOpts), |
|
|
|
Format = |
|
|
|
lists:append(["** gen_event handler ", P, " crashed.\n", |
|
|
|
lists:append(["** gen_emm handler ", P, " crashed.\n", |
|
|
|
"** Was installed in ", P, "\n", |
|
|
|
"** Last event was: ", P, "\n", |
|
|
|
"** When handler state == ", P, "\n", |
|
|
@ -891,22 +1007,6 @@ format_log_multi(#{label := {gen_event, terminate}, |
|
|
|
_ -> |
|
|
|
[Handler, Depth, SName, Depth, LastIn, Depth, State, Depth, Reason1, Depth] |
|
|
|
end, |
|
|
|
{Format, Args}; |
|
|
|
format_log_multi(#{label := {gen_event, no_handle_info}, |
|
|
|
module := Mod, |
|
|
|
message := Msg}, |
|
|
|
#{depth := Depth} = FormatOpts) -> |
|
|
|
P = p(FormatOpts), |
|
|
|
Format = |
|
|
|
"** Undefined handle_info in ~p\n" |
|
|
|
"** Unhandled message: " ++ P ++ "\n", |
|
|
|
Args = |
|
|
|
case Depth of |
|
|
|
unlimited -> |
|
|
|
[Mod, Msg]; |
|
|
|
_ -> |
|
|
|
[Mod, Msg, Depth] |
|
|
|
end, |
|
|
|
{Format, Args}. |
|
|
|
|
|
|
|
fix_reason({'EXIT', {undef, [{M, F, A, _L} | _] = MFAs} = Reason}) -> |
|
|
@ -942,10 +1042,10 @@ mod(_) -> "t". |
|
|
|
%% Message from the release_handler. |
|
|
|
%% The list of modules got to be a set, i.e. no duplicate elements! |
|
|
|
get_modules(EpmHers) -> |
|
|
|
allMods(maps:iterator(EpmHers), []). |
|
|
|
allMods(iterator(EpmHers), []). |
|
|
|
|
|
|
|
allMods(Iterator, Acc) -> |
|
|
|
case maps:next(Iterator) of |
|
|
|
case next(Iterator) of |
|
|
|
{_K, V, NextIterator} -> |
|
|
|
allMods(NextIterator, [element(#epmHer.epmM, V) | Acc]); |
|
|
|
_ -> |
|
|
@ -958,11 +1058,11 @@ allMods(Iterator, Acc) -> |
|
|
|
format_status(Opt, StatusData) -> |
|
|
|
[PDict, SysState, Parent, _Debug, {ServerName, _HibernateAfterTimeout, EpmHers, _IsHib}] = StatusData, |
|
|
|
Header = gen:format_status_header("Status for gen_emm handler", ServerName), |
|
|
|
FmtMSL = allStateStatus(maps:iterator(EpmHers), Opt, PDict, []), |
|
|
|
FmtMSL = allStateStatus(iterator(EpmHers), Opt, PDict, []), |
|
|
|
[{header, Header}, {data, [{"Status", SysState}, {"Parent", Parent}]}, {items, {"Installed handlers", FmtMSL}}]. |
|
|
|
|
|
|
|
allStateStatus(Iterator, Opt, PDict, EpmHers) -> |
|
|
|
case maps:next(Iterator) of |
|
|
|
case next(Iterator) of |
|
|
|
{_K, #epmHer{epmM = Module, epmS = EpmS} = V, NextIterator} -> |
|
|
|
NewEpmS = format_status(Opt, Module, PDict, EpmS), |
|
|
|
allStateStatus(NextIterator, Opt, PDict, [V#epmHer{epmS = NewEpmS} | EpmHers]); |
|
|
|