Преглед изворни кода

ft: gen_srv.erl 守护模式添加

master
SisMaker пре 1 година
родитељ
комит
46a295c5b9
2 измењених фајлова са 140 додато и 94 уклоњено
  1. +1
    -1
      src/gen_apu.erl
  2. +139
    -93
      src/gen_srv.erl

+ 1
- 1
src/gen_apu.erl Прегледај датотеку

@ -1042,7 +1042,7 @@ innerError(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers,
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),
error_msg({handleError, {IClass, IReason, IStrace}}, Name, undefined, {Class, Reason, Stacktrace}, Module, Debug, CurState),
kpS
end;
false ->

+ 139
- 93
src/gen_srv.erl Прегледај датотеку

@ -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}) ->

Loading…
Откажи
Сачувај