|
|
@ -33,7 +33,7 @@ |
|
|
|
, format_status/2 |
|
|
|
|
|
|
|
%% Internal callbacks |
|
|
|
, wakeupFromHib/7 |
|
|
|
, wakeupFromHib/8 |
|
|
|
|
|
|
|
%% logger callback |
|
|
|
, format_log/1, format_log/2, print_event/3 |
|
|
@ -126,6 +126,12 @@ |
|
|
|
{noreply, NewState :: term(), Actions :: actions()} | |
|
|
|
{stop, Reason :: term(), NewState :: term()}. |
|
|
|
|
|
|
|
-callback handleError(Error :: term(), State :: term()) -> |
|
|
|
kpS | |
|
|
|
{noreply, NewState :: term()} | |
|
|
|
{noreply, NewState :: term(), Actions :: actions()} | |
|
|
|
{stop, Reason :: term(), NewState :: term()}. |
|
|
|
|
|
|
|
-callback handleAfter(Info :: term(), State :: term()) -> |
|
|
|
kpS | |
|
|
|
{noreply, NewState :: term()} | |
|
|
@ -203,15 +209,16 @@ init_it(Starter, self, ServerRef, Module, Args, Options) -> |
|
|
|
init_it(Starter, Parent, ServerRef, Module, Args, Options) -> |
|
|
|
Name = gen:name(ServerRef), |
|
|
|
Debug = gen:debug_options(Name, Options), |
|
|
|
GbhOpts = #gbhOpts{daemon = lists:member(daemon, Options)}, |
|
|
|
HibernateAfterTimeout = gen:hibernate_after(Options), |
|
|
|
|
|
|
|
case doModuleInit(Module, Args) of |
|
|
|
{ok, State} -> |
|
|
|
proc_lib:init_ack(Starter, {ok, self()}), |
|
|
|
receiveIng(Parent, Name, Module, HibernateAfterTimeout, Debug, #{}, State, false); |
|
|
|
receiveIng(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, #{}, State, false); |
|
|
|
{ok, State, Actions} -> |
|
|
|
proc_lib:init_ack(Starter, {ok, self()}), |
|
|
|
loopEntry(Parent, Name, Module, HibernateAfterTimeout, Debug, #{}, State, listify(Actions)); |
|
|
|
loopEntry(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, #{}, State, listify(Actions)); |
|
|
|
{stop, Reason} -> |
|
|
|
% 为了保持一致性,我们必须确保在 |
|
|
|
% %%父进程收到有关失败的通知之前,必须先注销%%注册名称(如果有)。 |
|
|
@ -257,28 +264,29 @@ enter_loop(Module, State, Opts, ServerName, Actions) -> |
|
|
|
Name = gen:get_proc_name(ServerName), |
|
|
|
Parent = gen:get_parent(), |
|
|
|
Debug = gen:debug_options(Name, Opts), |
|
|
|
GbhOpts = #gbhOpts{daemon = lists:member(daemon, Opts)}, |
|
|
|
HibernateAfterTimeout = gen:hibernate_after(Opts), |
|
|
|
loopEntry(Parent, Name, Module, HibernateAfterTimeout, Debug, #{}, State, listify(Actions)). |
|
|
|
loopEntry(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, #{}, State, listify(Actions)). |
|
|
|
|
|
|
|
%%% Internal callbacks |
|
|
|
wakeupFromHib(Parent, Name, Module, HibernateAfterTimeout, Debug, Timers, CurState) -> |
|
|
|
wakeupFromHib(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, CurState) -> |
|
|
|
%% 这是一条新消息,唤醒了我们,因此我们必须立即收到它 |
|
|
|
receiveIng(Parent, Name, Module, HibernateAfterTimeout, Debug, Timers, CurState, true). |
|
|
|
receiveIng(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, CurState, true). |
|
|
|
|
|
|
|
loopEntry(Parent, Name, Module, HibernateAfterTimeout, Debug, Timers, CurState, Actions) -> |
|
|
|
loopEntry(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, CurState, Actions) -> |
|
|
|
case doParseAL(Actions, Name, Debug, false, false, Timers) of |
|
|
|
{error, ErrorContent} -> |
|
|
|
terminate(error, ErrorContent, ?STACKTRACE(), Name, Module, Debug, Timers, CurState, []); |
|
|
|
{NewDebug, IsHib, DoAfter, NewTimers} -> |
|
|
|
innerError(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, CurState, Actions, error, ErrorContent, []); |
|
|
|
{Debug, IsHib, DoAfter, NewTimers} -> |
|
|
|
case DoAfter of |
|
|
|
{doAfter, Args} -> |
|
|
|
doAfterCall(Parent, Name, Module, HibernateAfterTimeout, NewDebug, NewTimers, CurState, listHib(IsHib), Args); |
|
|
|
doAfterCall(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, NewTimers, CurState, listHib(IsHib), Args); |
|
|
|
_ -> |
|
|
|
case IsHib of |
|
|
|
true -> |
|
|
|
proc_lib:hibernate(?MODULE, wakeupFromHib, [Parent, Name, Module, HibernateAfterTimeout, NewDebug, NewTimers, CurState]); |
|
|
|
proc_lib:hibernate(?MODULE, wakeupFromHib, [Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, NewTimers, CurState]); |
|
|
|
_ -> |
|
|
|
receiveIng(Parent, Name, Module, HibernateAfterTimeout, NewDebug, NewTimers, CurState, false) |
|
|
|
receiveIng(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, NewTimers, CurState, false) |
|
|
|
end |
|
|
|
end |
|
|
|
end. |
|
|
@ -287,19 +295,19 @@ loopEntry(Parent, Name, Module, HibernateAfterTimeout, Debug, Timers, CurState, |
|
|
|
%%----------------------------------------------------------------- |
|
|
|
%% Callback functions for system messages handling. |
|
|
|
%%----------------------------------------------------------------- |
|
|
|
system_continue(Parent, Debug, {Name, Module, HibernateAfterTimeout, Timers, CurState, IsHib}) -> |
|
|
|
system_continue(Parent, Debug, {Name, Module, GbhOpts, HibernateAfterTimeout, Timers, CurState, IsHib}) -> |
|
|
|
case IsHib of |
|
|
|
true -> |
|
|
|
proc_lib:hibernate(?MODULE, wakeupFromHib, [Parent, Name, Module, HibernateAfterTimeout, Debug, Timers, CurState]); |
|
|
|
proc_lib:hibernate(?MODULE, wakeupFromHib, [Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, CurState]); |
|
|
|
_ -> |
|
|
|
receiveIng(Parent, Name, Module, HibernateAfterTimeout, Debug, Timers, CurState, false) |
|
|
|
receiveIng(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, CurState, false) |
|
|
|
end. |
|
|
|
|
|
|
|
-spec system_terminate(_, _, _, [_]) -> no_return(). |
|
|
|
system_terminate(Reason, _Parent, Debug, {Name, Module, _HibernateAfterTimeout, Timers, CurState, _IsHib}) -> |
|
|
|
system_terminate(Reason, _Parent, Debug, {Name, Module, _GbhOpts, _HibernateAfterTimeout, Timers, CurState, _IsHib}) -> |
|
|
|
terminate(exit, Reason, ?STACKTRACE(), Name, Module, Debug, Timers, CurState, []). |
|
|
|
|
|
|
|
system_code_change({Name, Module, HibernateAfterTimeout, Timers, CurState, IsHib}, _Module, OldVsn, Extra) -> |
|
|
|
system_code_change({Name, Module, GbhOpts, HibernateAfterTimeout, Timers, CurState, IsHib}, _Module, OldVsn, Extra) -> |
|
|
|
case |
|
|
|
try Module:code_change(OldVsn, CurState, Extra) |
|
|
|
catch |
|
|
@ -307,16 +315,16 @@ system_code_change({Name, Module, HibernateAfterTimeout, Timers, CurState, IsHib |
|
|
|
_C:_R:_S -> {_C, _R, _S} |
|
|
|
end |
|
|
|
of |
|
|
|
{ok, NewState} -> {ok, {Name, Module, HibernateAfterTimeout, Timers, NewState, IsHib}}; |
|
|
|
{ok, NewState} -> {ok, {Name, Module, GbhOpts, HibernateAfterTimeout, Timers, NewState, IsHib}}; |
|
|
|
Error -> Error |
|
|
|
end. |
|
|
|
|
|
|
|
system_get_state({_Name, _Module, _HibernateAfterTimeout, _Timers, CurState, _IsHib}) -> |
|
|
|
system_get_state({_Name, _Module, _GbhOpts, _HibernateAfterTimeout, _Timers, CurState, _IsHib}) -> |
|
|
|
{ok, CurState}. |
|
|
|
|
|
|
|
system_replace_state(StateFun, {Name, Module, HibernateAfterTimeout, Timers, CurState, IsHib}) -> |
|
|
|
system_replace_state(StateFun, {Name, Module, GbhOpts, HibernateAfterTimeout, Timers, CurState, IsHib}) -> |
|
|
|
NewState = StateFun(CurState), |
|
|
|
{ok, NewState, {Name, Module, HibernateAfterTimeout, Timers, NewState, IsHib}}. |
|
|
|
{ok, NewState, {Name, Module, GbhOpts, HibernateAfterTimeout, Timers, NewState, IsHib}}. |
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% sys callbacks end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
|
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% API helpers start %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
@ -694,68 +702,68 @@ start_monitor(Node, Name) when is_atom(Node), is_atom(Name) -> |
|
|
|
|
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% API helpers end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
|
|
|
|
|
receiveIng(Parent, Name, Module, HibernateAfterTimeout, Debug, Timers, CurState, IsHib) -> |
|
|
|
receiveIng(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, CurState, IsHib) -> |
|
|
|
receive |
|
|
|
Msg -> |
|
|
|
case Msg of |
|
|
|
{'$gen_call', From, Request} -> |
|
|
|
matchCallMsg(Parent, Name, Module, HibernateAfterTimeout, Debug, Timers, CurState, From, Request); |
|
|
|
matchCallMsg(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, CurState, From, Request); |
|
|
|
{'$gen_cast', Cast} -> |
|
|
|
matchCastMsg(Parent, Name, Module, HibernateAfterTimeout, Debug, Timers, CurState, Cast); |
|
|
|
matchCastMsg(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, CurState, Cast); |
|
|
|
{'$gen_clfn', From, MFA} -> |
|
|
|
matchMFA(Parent, Name, Module, HibernateAfterTimeout, Debug, Timers, CurState, From, MFA, false); |
|
|
|
matchMFA(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, CurState, From, MFA, false); |
|
|
|
{'$gen_clfs', From, MFA} -> |
|
|
|
matchMFA(Parent, Name, Module, HibernateAfterTimeout, Debug, Timers, CurState, From, MFA, true); |
|
|
|
matchMFA(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, CurState, From, MFA, true); |
|
|
|
{'$gen_csfn', MFA} -> |
|
|
|
matchMFA(Parent, Name, Module, HibernateAfterTimeout, Debug, Timers, CurState, false, MFA, false); |
|
|
|
matchMFA(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, CurState, false, MFA, false); |
|
|
|
{'$gen_csfs', MFA} -> |
|
|
|
matchMFA(Parent, Name, Module, HibernateAfterTimeout, Debug, Timers, CurState, false, MFA, true); |
|
|
|
matchMFA(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, CurState, false, MFA, true); |
|
|
|
{timeout, TimerRef, TimeoutName} -> |
|
|
|
case Timers of |
|
|
|
#{TimeoutName := {TimerRef, TimeoutMsg}} -> |
|
|
|
NewTimer = maps:remove(TimeoutName, Timers), |
|
|
|
matchInfoMsg(Parent, Name, Module, HibernateAfterTimeout, Debug, NewTimer, CurState, TimeoutMsg); |
|
|
|
matchInfoMsg(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, NewTimer, CurState, TimeoutMsg); |
|
|
|
_ -> |
|
|
|
matchInfoMsg(Parent, Name, Module, HibernateAfterTimeout, Debug, Timers, CurState, Msg) |
|
|
|
matchInfoMsg(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, CurState, Msg) |
|
|
|
end; |
|
|
|
{system, PidFrom, Request} -> |
|
|
|
%% 不返回但尾递归调用 system_continue/3 |
|
|
|
sys:handle_system_msg(Request, PidFrom, Parent, ?MODULE, Debug, {Name, Module, HibernateAfterTimeout, Timers, CurState, IsHib}, IsHib); |
|
|
|
sys:handle_system_msg(Request, PidFrom, Parent, ?MODULE, Debug, {Name, Module, GbhOpts, HibernateAfterTimeout, Timers, CurState, IsHib}, IsHib); |
|
|
|
{'EXIT', Parent, Reason} -> |
|
|
|
terminate(exit, Reason, ?STACKTRACE(), Name, Module, Debug, Timers, CurState, Msg); |
|
|
|
_ -> |
|
|
|
matchInfoMsg(Parent, Name, Module, HibernateAfterTimeout, Debug, Timers, CurState, Msg) |
|
|
|
matchInfoMsg(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, CurState, Msg) |
|
|
|
end |
|
|
|
after HibernateAfterTimeout -> |
|
|
|
proc_lib:hibernate(?MODULE, wakeupFromHib, [Parent, Name, Module, HibernateAfterTimeout, Debug, Timers, CurState]) |
|
|
|
proc_lib:hibernate(?MODULE, wakeupFromHib, [Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, CurState]) |
|
|
|
end. |
|
|
|
|
|
|
|
matchCallMsg(Parent, Name, Module, HibernateAfterTimeout, Debug, Timers, CurState, From, Request) -> |
|
|
|
NewDebug = ?SYS_DEBUG(Debug, Name, {in, {{call, From}, Request}}), |
|
|
|
matchCallMsg(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, CurState, From, Request) -> |
|
|
|
?SYS_DEBUG(Debug, Name, {in, {{call, From}, Request}}), |
|
|
|
try Module:handleCall(Request, CurState, From) of |
|
|
|
Result -> |
|
|
|
handleCR(Parent, Name, Module, HibernateAfterTimeout, NewDebug, Timers, CurState, Result, From, false) |
|
|
|
handleCR(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, CurState, Result, From, false) |
|
|
|
catch |
|
|
|
throw:Result -> |
|
|
|
handleCR(Parent, Name, Module, HibernateAfterTimeout, NewDebug, Timers, CurState, Result, From, false); |
|
|
|
handleCR(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, CurState, Result, From, false); |
|
|
|
Class:Reason:Strace -> |
|
|
|
terminate(Class, Reason, Strace, Name, Module, NewDebug, Timers, CurState, {{call, From}, Request}) |
|
|
|
innerError(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, CurState, {{call, From}, Request}, Class, Reason, Strace) |
|
|
|
end. |
|
|
|
|
|
|
|
matchCastMsg(Parent, Name, Module, HibernateAfterTimeout, Debug, Timers, CurState, Cast) -> |
|
|
|
NewDebug = ?SYS_DEBUG(Debug, Name, {in, {cast, Cast}}), |
|
|
|
matchCastMsg(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, CurState, Cast) -> |
|
|
|
?SYS_DEBUG(Debug, Name, {in, {cast, Cast}}), |
|
|
|
try Module:handleCast(Cast, CurState) of |
|
|
|
Result -> |
|
|
|
handleCR(Parent, Name, Module, HibernateAfterTimeout, NewDebug, Timers, CurState, Result, false, false) |
|
|
|
handleCR(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, CurState, Result, false, false) |
|
|
|
catch |
|
|
|
throw:Result -> |
|
|
|
handleCR(Parent, Name, Module, HibernateAfterTimeout, NewDebug, Timers, CurState, Result, false, false); |
|
|
|
handleCR(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, CurState, Result, false, false); |
|
|
|
Class:Reason:Strace -> |
|
|
|
terminate(Class, Reason, Strace, Name, Module, NewDebug, Timers, CurState, {cast, Cast}) |
|
|
|
innerError(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, CurState, {cast, Cast}, Class, Reason, Strace) |
|
|
|
end. |
|
|
|
|
|
|
|
matchMFA(Parent, Name, Module, HibernateAfterTimeout, Debug, Timers, CurState, From, MFA, IsWithState) -> |
|
|
|
NewDebug = ?SYS_DEBUG(Debug, Name, {in, {mfa, MFA}}), |
|
|
|
matchMFA(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, CurState, From, MFA, IsWithState) -> |
|
|
|
?SYS_DEBUG(Debug, Name, {in, {mfa, MFA}}), |
|
|
|
try |
|
|
|
{M, F, A} = MFA, |
|
|
|
case IsWithState of |
|
|
@ -766,115 +774,116 @@ matchMFA(Parent, Name, Module, HibernateAfterTimeout, Debug, Timers, CurState, F |
|
|
|
end |
|
|
|
of |
|
|
|
Result -> |
|
|
|
handleCR(Parent, Name, Module, HibernateAfterTimeout, NewDebug, Timers, CurState, Result, From, true) |
|
|
|
handleCR(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, CurState, Result, From, true) |
|
|
|
catch |
|
|
|
throw:Result -> |
|
|
|
handleCR(Parent, Name, Module, HibernateAfterTimeout, NewDebug, Timers, CurState, Result, From, true); |
|
|
|
handleCR(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, CurState, Result, From, true); |
|
|
|
error:undef -> |
|
|
|
try_greply(From, {error, undef}), |
|
|
|
receiveIng(Parent, Name, Module, HibernateAfterTimeout, NewDebug, Timers, CurState, false); |
|
|
|
receiveIng(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, CurState, false); |
|
|
|
Class:Reason:Strace -> |
|
|
|
terminate(Class, Reason, Strace, Name, Module, NewDebug, Timers, CurState, {mfa, MFA}) |
|
|
|
try_greply(From, {error, {inner_error, {Class, Reason, Strace}}}), |
|
|
|
innerError(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, CurState, {mfa, MFA}, Class, Reason, Strace) |
|
|
|
end. |
|
|
|
|
|
|
|
matchInfoMsg(Parent, Name, Module, HibernateAfterTimeout, Debug, Timers, CurState, Msg) -> |
|
|
|
NewDebug = ?SYS_DEBUG(Debug, Name, {in, {info, Msg}}), |
|
|
|
matchInfoMsg(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, CurState, Msg) -> |
|
|
|
?SYS_DEBUG(Debug, Name, {in, {info, Msg}}), |
|
|
|
try Module:handleInfo(Msg, CurState) of |
|
|
|
Result -> |
|
|
|
handleCR(Parent, Name, Module, HibernateAfterTimeout, NewDebug, Timers, CurState, Result, false, false) |
|
|
|
handleCR(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, CurState, Result, false, false) |
|
|
|
catch |
|
|
|
throw:Result -> |
|
|
|
handleCR(Parent, Name, Module, HibernateAfterTimeout, NewDebug, Timers, CurState, Result, false, false); |
|
|
|
handleCR(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, CurState, Result, false, false); |
|
|
|
Class:Reason:Strace -> |
|
|
|
terminate(Class, Reason, Strace, Name, Module, NewDebug, Timers, CurState, {info, Msg}) |
|
|
|
innerError(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, CurState, {info, Msg}, Class, Reason, Strace) |
|
|
|
end. |
|
|
|
|
|
|
|
doAfterCall(Parent, Name, Module, HibernateAfterTimeout, Debug, Timers, CurState, LeftAction, Args) -> |
|
|
|
NewDebug = ?SYS_DEBUG(Debug, Name, {in, {doAfter, Args}}), |
|
|
|
doAfterCall(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, CurState, LeftAction, Args) -> |
|
|
|
?SYS_DEBUG(Debug, Name, {in, {doAfter, Args}}), |
|
|
|
try Module:handleAfter(Args, CurState) of |
|
|
|
Result -> |
|
|
|
handleAR(Parent, Name, Module, HibernateAfterTimeout, NewDebug, Timers, CurState, LeftAction, Result) |
|
|
|
handleAR(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, CurState, LeftAction, Result) |
|
|
|
catch |
|
|
|
throw:Result -> |
|
|
|
handleAR(Parent, Name, Module, HibernateAfterTimeout, NewDebug, Timers, CurState, LeftAction, Result); |
|
|
|
handleAR(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, CurState, LeftAction, Result); |
|
|
|
Class:Reason:Strace -> |
|
|
|
terminate(Class, Reason, Strace, Name, Module, NewDebug, Timers, CurState, {doAfter, Args}) |
|
|
|
innerError(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, CurState, {doAfter, Args}, Class, Reason, Strace) |
|
|
|
end. |
|
|
|
|
|
|
|
handleCR(Parent, Name, Module, HibernateAfterTimeout, Debug, Timers, CurState, Result, From, IsAnyRet) -> |
|
|
|
handleCR(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, CurState, Result, From, IsAnyRet) -> |
|
|
|
case Result of |
|
|
|
kpS -> |
|
|
|
receiveIng(Parent, Name, Module, HibernateAfterTimeout, Debug, Timers, CurState, false); |
|
|
|
receiveIng(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, CurState, false); |
|
|
|
{reply, Reply} -> |
|
|
|
greply(From, Reply), |
|
|
|
NewDebug = ?SYS_DEBUG(Debug, Name, {out, Reply, From, CurState}), |
|
|
|
receiveIng(Parent, Name, Module, HibernateAfterTimeout, NewDebug, Timers, CurState, false); |
|
|
|
?SYS_DEBUG(Debug, Name, {out, Reply, From, CurState}), |
|
|
|
receiveIng(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, CurState, false); |
|
|
|
{mayReply, Reply} -> |
|
|
|
case From of |
|
|
|
false -> |
|
|
|
receiveIng(Parent, Name, Module, HibernateAfterTimeout, Debug, Timers, CurState, false); |
|
|
|
receiveIng(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, CurState, false); |
|
|
|
_ -> |
|
|
|
greply(From, Reply), |
|
|
|
NewDebug = ?SYS_DEBUG(Debug, Name, {out, Reply, From, CurState}), |
|
|
|
receiveIng(Parent, Name, Module, HibernateAfterTimeout, NewDebug, Timers, CurState, false) |
|
|
|
?SYS_DEBUG(Debug, Name, {out, Reply, From, CurState}), |
|
|
|
receiveIng(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, CurState, false) |
|
|
|
end; |
|
|
|
{noreply, NewState} -> |
|
|
|
receiveIng(Parent, Name, Module, HibernateAfterTimeout, Debug, Timers, NewState, false); |
|
|
|
receiveIng(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, NewState, false); |
|
|
|
{reply, Reply, NewState} -> |
|
|
|
greply(From, Reply), |
|
|
|
NewDebug = ?SYS_DEBUG(Debug, Name, {out, Reply, From, NewState}), |
|
|
|
receiveIng(Parent, Name, Module, HibernateAfterTimeout, NewDebug, Timers, NewState, false); |
|
|
|
?SYS_DEBUG(Debug, Name, {out, Reply, From, NewState}), |
|
|
|
receiveIng(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, NewState, false); |
|
|
|
{mayReply, Reply, NewState} -> |
|
|
|
case From of |
|
|
|
false -> |
|
|
|
receiveIng(Parent, Name, Module, HibernateAfterTimeout, Debug, Timers, NewState, false); |
|
|
|
receiveIng(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, NewState, false); |
|
|
|
_ -> |
|
|
|
greply(From, Reply), |
|
|
|
NewDebug = ?SYS_DEBUG(Debug, Name, {out, Reply, From, NewState}), |
|
|
|
receiveIng(Parent, Name, Module, HibernateAfterTimeout, NewDebug, Timers, NewState, false) |
|
|
|
?SYS_DEBUG(Debug, Name, {out, Reply, From, NewState}), |
|
|
|
receiveIng(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, NewState, false) |
|
|
|
end; |
|
|
|
{noreply, NewState, Actions} -> |
|
|
|
loopEntry(Parent, Name, Module, HibernateAfterTimeout, Debug, Timers, NewState, listify(Actions)); |
|
|
|
loopEntry(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, NewState, listify(Actions)); |
|
|
|
{stop, Reason, NewState} -> |
|
|
|
terminate(exit, Reason, ?STACKTRACE(), Name, Module, Debug, Timers, NewState, {return, stop}); |
|
|
|
{reply, Reply, NewState, Actions} -> |
|
|
|
greply(From, Reply), |
|
|
|
NewDebug = ?SYS_DEBUG(Debug, Name, {out, Reply, From, NewState}), |
|
|
|
loopEntry(Parent, Name, Module, HibernateAfterTimeout, NewDebug, Timers, NewState, listify(Actions)); |
|
|
|
?SYS_DEBUG(Debug, Name, {out, Reply, From, NewState}), |
|
|
|
loopEntry(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, NewState, listify(Actions)); |
|
|
|
{mayReply, Reply, NewState, Actions} -> |
|
|
|
case From of |
|
|
|
false -> |
|
|
|
loopEntry(Parent, Name, Module, HibernateAfterTimeout, Debug, Timers, NewState, listify(Actions)); |
|
|
|
loopEntry(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, NewState, listify(Actions)); |
|
|
|
_ -> |
|
|
|
|
|
|
|
greply(From, Reply), |
|
|
|
NewDebug = ?SYS_DEBUG(Debug, Name, {out, Reply, From, NewState}), |
|
|
|
loopEntry(Parent, Name, Module, HibernateAfterTimeout, NewDebug, Timers, NewState, listify(Actions)) |
|
|
|
?SYS_DEBUG(Debug, Name, {out, Reply, From, NewState}), |
|
|
|
loopEntry(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, NewState, listify(Actions)) |
|
|
|
end; |
|
|
|
{stopReply, Reason, Reply, NewState} -> |
|
|
|
NewDebug = ?SYS_DEBUG(Debug, Name, {out, Reply, From, NewState}), |
|
|
|
?SYS_DEBUG(Debug, Name, {out, Reply, From, NewState}), |
|
|
|
try |
|
|
|
terminate(exit, Reason, ?STACKTRACE(), Name, Module, NewDebug, Timers, NewState, {return, stop_reply}) |
|
|
|
terminate(exit, Reason, ?STACKTRACE(), Name, Module, Debug, Timers, NewState, {return, stop_reply}) |
|
|
|
after |
|
|
|
_ = greply(From, Reply) |
|
|
|
end; |
|
|
|
_AnyRet -> |
|
|
|
case IsAnyRet of |
|
|
|
true -> |
|
|
|
receiveIng(Parent, Name, Module, HibernateAfterTimeout, Debug, Timers, CurState, false); |
|
|
|
receiveIng(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, CurState, false); |
|
|
|
_ -> |
|
|
|
terminate(exit, bad_ret, ?STACKTRACE(), Name, Module, Debug, Timers, CurState, {return, _AnyRet}) |
|
|
|
innerError(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, CurState, {return, _AnyRet}, error, bad_ret, ?STACKTRACE()) |
|
|
|
end |
|
|
|
end. |
|
|
|
|
|
|
|
handleAR(Parent, Name, Module, HibernateAfterTimeout, Debug, Timers, CurState, LeftAction, Result) -> |
|
|
|
handleAR(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, CurState, LeftAction, Result) -> |
|
|
|
case Result of |
|
|
|
kpS -> |
|
|
|
loopEntry(Parent, Name, Module, HibernateAfterTimeout, Debug, Timers, CurState, LeftAction); |
|
|
|
loopEntry(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, CurState, LeftAction); |
|
|
|
{noreply, NewState} -> |
|
|
|
loopEntry(Parent, Name, Module, HibernateAfterTimeout, Debug, Timers, NewState, LeftAction); |
|
|
|
loopEntry(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, NewState, LeftAction); |
|
|
|
{noreply, NewState, Actions} -> |
|
|
|
loopEntry(Parent, Name, Module, HibernateAfterTimeout, Debug, Timers, NewState, listify(Actions) ++ LeftAction); |
|
|
|
loopEntry(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, NewState, listify(Actions) ++ LeftAction); |
|
|
|
{stop, Reason, NewState} -> |
|
|
|
terminate(exit, Reason, ?STACKTRACE(), Name, Module, Debug, Timers, NewState, {return, stop_reply}) |
|
|
|
end. |
|
|
@ -895,9 +904,9 @@ doParseAL([OneAction | LeftActions], Name, Debug, IsHib, DoAfter, Timers) -> |
|
|
|
doParseAL(LeftActions, Name, Debug, IsHib, DoAfter, NewTimers); |
|
|
|
_ -> |
|
|
|
TimerRef = erlang:start_timer(Time, self(), TimeoutName, Options), |
|
|
|
NewDebug = ?SYS_DEBUG(Debug, Name, {start_timer, {TimeoutName, Time, TimeoutMsg, Options}}), |
|
|
|
?SYS_DEBUG(Debug, Name, {start_timer, {TimeoutName, Time, TimeoutMsg, Options}}), |
|
|
|
NewTimers = doRegisterTimer(TimeoutName, TimerRef, TimeoutMsg, Timers), |
|
|
|
doParseAL(LeftActions, Name, NewDebug, IsHib, DoAfter, NewTimers) |
|
|
|
doParseAL(LeftActions, Name, Debug, IsHib, DoAfter, NewTimers) |
|
|
|
end; |
|
|
|
{'nTimeout', TimeoutName, Time, TimeoutMsg} -> |
|
|
|
case Time of |
|
|
@ -906,9 +915,9 @@ doParseAL([OneAction | LeftActions], Name, Debug, IsHib, DoAfter, Timers) -> |
|
|
|
doParseAL(LeftActions, Name, Debug, IsHib, DoAfter, NewTimers); |
|
|
|
_ -> |
|
|
|
TimerRef = erlang:start_timer(Time, self(), TimeoutName), |
|
|
|
NewDebug = ?SYS_DEBUG(Debug, Name, {start_timer, {TimeoutName, Time, TimeoutMsg, []}}), |
|
|
|
?SYS_DEBUG(Debug, Name, {start_timer, {TimeoutName, Time, TimeoutMsg, []}}), |
|
|
|
NewTimers = doRegisterTimer(TimeoutName, TimerRef, TimeoutMsg, Timers), |
|
|
|
doParseAL(LeftActions, Name, NewDebug, IsHib, DoAfter, NewTimers) |
|
|
|
doParseAL(LeftActions, Name, Debug, IsHib, DoAfter, NewTimers) |
|
|
|
end; |
|
|
|
{'uTimeout', TimeoutName, NewTimeoutMsg} -> |
|
|
|
NewTimers = doUpdateTimer(TimeoutName, NewTimeoutMsg, Timers), |
|
|
@ -920,8 +929,8 @@ doParseAL([OneAction | LeftActions], Name, Debug, IsHib, DoAfter, Timers) -> |
|
|
|
doParseAL(LeftActions, Name, Debug, IsHib, DoAfter, Timers); |
|
|
|
Timeout when is_integer(Timeout) -> |
|
|
|
erlang:send_after(Timeout, self(), timeout), |
|
|
|
NewDebug = ?SYS_DEBUG(Debug, Name, {start_timer, {timeout, Timeout, timeout, []}}), |
|
|
|
doParseAL(LeftActions, Name, NewDebug, IsHib, DoAfter, Timers); |
|
|
|
?SYS_DEBUG(Debug, Name, {start_timer, {timeout, Timeout, timeout, []}}), |
|
|
|
doParseAL(LeftActions, Name, Debug, IsHib, DoAfter, Timers); |
|
|
|
_ -> |
|
|
|
{error, {bad_ActionType, OneAction}} |
|
|
|
end. |
|
|
@ -993,7 +1002,28 @@ listHib(false) -> |
|
|
|
listHib(_) -> |
|
|
|
[hibernate]. |
|
|
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% timer deal end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
|
|
|
|
|
|
|
innerError(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, CurState, MsgEvent, Class, Reason, Stacktrace) -> |
|
|
|
case GbhOpts of |
|
|
|
#gbhOpts{daemon = true} -> |
|
|
|
error_msg({innerError, {Class, Reason, Stacktrace}}, Name, undefined, MsgEvent, Module, Debug, CurState), |
|
|
|
case erlang:function_exported(Module, handleError, 2) of |
|
|
|
true -> |
|
|
|
try Module:handleError({Class, Reason, Stacktrace}, CurState) of |
|
|
|
Result -> |
|
|
|
handleCR(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, CurState, Result, false, false) |
|
|
|
catch |
|
|
|
throw:Result -> |
|
|
|
handleCR(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, CurState, Result, false, false); |
|
|
|
IClass:IReason:IStrace -> |
|
|
|
error_msg({handleError, {IClass, IReason, IStrace}}, Name, undefined, {Class, Reason, Stacktrace}, Module, Debug, CurState), |
|
|
|
kpS |
|
|
|
end; |
|
|
|
false -> |
|
|
|
kpS |
|
|
|
end; |
|
|
|
_ -> |
|
|
|
terminate(Class, Reason, Stacktrace, Name, Module, Debug, Timers, CurState, MsgEvent) |
|
|
|
end. |
|
|
|
|
|
|
|
%%% --------------------------------------------------- |
|
|
|
%%% Terminate the server. |
|
|
@ -1072,6 +1102,22 @@ error_info(Reason, Name, From, Msg, Module, Debug, State) -> |
|
|
|
}), |
|
|
|
ok. |
|
|
|
|
|
|
|
error_msg(Reason, Name, From, Msg, Module, Debug, State) -> |
|
|
|
Log = sys:get_log(Debug), |
|
|
|
?LOG_ERROR(#{label => {gen_srv, inner_error}, |
|
|
|
name => Name, |
|
|
|
last_message => Msg, |
|
|
|
state => format_status(inner_error, Module, get(), State), |
|
|
|
log => format_log_state(Module, Log), |
|
|
|
reason => Reason, |
|
|
|
client_info => client_stacktrace(From)}, |
|
|
|
#{ |
|
|
|
domain => [otp], |
|
|
|
report_cb => fun gen_srv:format_log/2, |
|
|
|
error_logger => #{tag => error, report_cb => fun gen_srv:format_log/1} |
|
|
|
}), |
|
|
|
ok. |
|
|
|
|
|
|
|
client_stacktrace(undefined) -> |
|
|
|
undefined; |
|
|
|
client_stacktrace({From, _Tag}) -> |
|
|
|