Просмотр исходного кода

ft: gen_mpp.erl 守护模式添加

master
lijie 1 год назад
Родитель
Сommit
e4fcbed817
2 измененных файлов: 139 добавлений и 90 удалений
  1. +137
    -89
      src/gen_mpp.erl
  2. +2
    -1
      src/gen_srv.erl

+ 137
- 89
src/gen_mpp.erl Просмотреть файл

@ -33,7 +33,7 @@
, format_status/2 , format_status/2
%% Internal callbacks %% Internal callbacks
, wakeupFromHib/7
, wakeupFromHib/8
%% logger callback %% logger callback
, format_log/1, format_log/2, print_event/3 , format_log/1, format_log/2, print_event/3
@ -121,6 +121,12 @@
{noreply, NewState :: term(), Actions :: actions()} | {noreply, NewState :: term(), Actions :: actions()} |
{stop, Reason :: term(), NewState :: term()}. {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()) -> -callback handleAfter(Info :: term(), State :: term()) ->
kpS | kpS |
{noreply, NewState :: term()} | {noreply, NewState :: term()} |
@ -143,6 +149,7 @@
-optional_callbacks([ -optional_callbacks([
handleAfter/2 handleAfter/2
, handleInfo/2 , handleInfo/2
, handleError/2
, terminate/2 , terminate/2
, code_change/3 , code_change/3
, formatStatus/2 , formatStatus/2
@ -199,15 +206,16 @@ init_it(Starter, self, ServerRef, Module, Args, Options) ->
init_it(Starter, Parent, ServerRef, Module, Args, Options) -> init_it(Starter, Parent, ServerRef, Module, Args, Options) ->
Name = gen:name(ServerRef), Name = gen:name(ServerRef),
Debug = gen:debug_options(Name, Options), Debug = gen:debug_options(Name, Options),
GbhOpts = #gbhOpts{daemon = lists:member(daemon, Options)},
HibernateAfterTimeout = gen:hibernate_after(Options), HibernateAfterTimeout = gen:hibernate_after(Options),
case doModuleInit(Module, Args) of case doModuleInit(Module, Args) of
{ok, State} -> {ok, State} ->
proc_lib:init_ack(Starter, {ok, self()}), 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} -> {ok, State, Actions} ->
proc_lib:init_ack(Starter, {ok, self()}), 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} -> {stop, Reason} ->
% %
% %%%% % %%%%
@ -254,28 +262,29 @@ enter_loop(Module, State, Opts, ServerName, Actions) ->
Name = gen:get_proc_name(ServerName), Name = gen:get_proc_name(ServerName),
Parent = gen:get_parent(), Parent = gen:get_parent(),
Debug = gen:debug_options(Name, Opts), Debug = gen:debug_options(Name, Opts),
GbhOpts = #gbhOpts{daemon = lists:member(daemon, Opts)},
HibernateAfterTimeout = gen:hibernate_after(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 %%% 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 case doParseAL(Actions, Name, Debug, false, false, Timers) of
{error, ErrorContent} -> {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, ?STACKTRACE());
{Debug, IsHib, DoAfter, NewTimers} ->
case DoAfter of case DoAfter of
{doAfter, Args} -> {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 case IsHib of
true -> 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 end
end. end.
@ -284,19 +293,19 @@ loopEntry(Parent, Name, Module, HibernateAfterTimeout, Debug, Timers, CurState,
%%----------------------------------------------------------------- %%-----------------------------------------------------------------
%% Callback functions for system messages handling. %% 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 case IsHib of
true -> 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. end.
-spec system_terminate(_, _, _, [_]) -> no_return(). -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, []). 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 case
try Module:code_change(OldVsn, CurState, Extra) try Module:code_change(OldVsn, CurState, Extra)
catch catch
@ -304,16 +313,16 @@ system_code_change({Name, Module, HibernateAfterTimeout, Timers, CurState, IsHib
_C:_R:_S -> {_C, _R, _S} _C:_R:_S -> {_C, _R, _S}
end end
of of
{ok, NewState} -> {ok, {Name, Module, HibernateAfterTimeout, Timers, NewState, IsHib}};
{ok, NewState} -> {ok, {Name, Module, GbhOpts, HibernateAfterTimeout, Timers, NewState, IsHib}};
Error -> Error Error -> Error
end. end.
system_get_state({_Name, _Module, _HibernateAfterTimeout, _Timers, CurState, _IsHib}) ->
system_get_state({_Name, _Module, _GbhOpts, _HibernateAfterTimeout, _Timers, CurState, _IsHib}) ->
{ok, CurState}. {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), NewState = StateFun(CurState),
{ok, NewState, {Name, Module, HibernateAfterTimeout, Timers, NewState, IsHib}}.
{ok, NewState, {Name, Module, GbhOpts, HibernateAfterTimeout, Timers, NewState, IsHib}}.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% sys callbacks end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% sys callbacks end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% API helpers start %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% API helpers start %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -691,36 +700,36 @@ start_monitor(Node, Name) when is_atom(Node), is_atom(Name) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% API helpers end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% API helpers end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
receiveIng(Parent, Name, Module, HibernateAfterTimeout, Debug, Timers, CurState, IsHib) ->
receiveIng(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, CurState, IsHib) ->
receive receive
Msg -> Msg ->
case Msg of case Msg of
{'$gen_call', From, Request} -> {'$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} -> {'$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} -> {'$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} -> {'$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} -> {'$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} -> {'$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);
{system, PidFrom, Request} -> {system, PidFrom, Request} ->
%% system_continue/3 %% 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} -> {'EXIT', Parent, Reason} ->
terminate(exit, Reason, ?STACKTRACE(), Name, Module, Debug, Timers, CurState, Msg); 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 end
after HibernateAfterTimeout -> 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. 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 try
case is_tuple(Request) of case is_tuple(Request) of
true -> true ->
@ -731,19 +740,20 @@ matchCallMsg(Parent, Name, Module, HibernateAfterTimeout, Debug, Timers, CurStat
end end
of of
Result -> 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 catch
throw:Result -> 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);
error:undef -> error:undef ->
try_greply(From, {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 -> Class:Reason:Strace ->
terminate(Class, Reason, Strace, Name, Module, NewDebug, Timers, CurState, {{call, From}, Request})
try_greply(From, {error, {inner_error, {Class, Reason, Strace}}}),
innerError(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, CurState, {{call, From}, Request}, Class, Reason, Strace)
end. 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 try
case is_tuple(Cast) of case is_tuple(Cast) of
true -> true ->
@ -754,18 +764,18 @@ matchCastMsg(Parent, Name, Module, HibernateAfterTimeout, Debug, Timers, CurStat
end end
of of
Result -> 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 catch
throw:Result -> 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);
error:undef -> error:undef ->
receiveIng(Parent, Name, Module, HibernateAfterTimeout, NewDebug, Timers, CurState, false);
receiveIng(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, CurState, false);
Class:Reason:Strace -> 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. 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 try
{M, F, A} = MFA, {M, F, A} = MFA,
case IsWithState of case IsWithState of
@ -776,115 +786,116 @@ matchMFA(Parent, Name, Module, HibernateAfterTimeout, Debug, Timers, CurState, F
end end
of of
Result -> 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 catch
throw:Result -> 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 -> error:undef ->
try_greply(From, {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 -> 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. 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 try Module:handleInfo(Msg, CurState) of
Result -> 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 catch
throw:Result -> 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 -> 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. 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 try Module:handleAfter(Args, CurState) of
Result -> Result ->
handleAR(Parent, Name, Module, HibernateAfterTimeout, NewDebug, Timers, CurState, LeftAction, Result)
handleAR(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, CurState, LeftAction, Result)
catch catch
throw:Result -> 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 -> 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. 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 case Result of
kpS -> kpS ->
receiveIng(Parent, Name, Module, HibernateAfterTimeout, Debug, Timers, CurState, false);
receiveIng(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, CurState, false);
{reply, Reply} -> {reply, Reply} ->
reply(From, Reply), reply(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} -> {mayReply, Reply} ->
case From of case From of
false -> false ->
receiveIng(Parent, Name, Module, HibernateAfterTimeout, Debug, Timers, CurState, false);
receiveIng(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, CurState, false);
_ -> _ ->
greply(From, 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)
end; end;
{noreply, NewState} -> {noreply, NewState} ->
receiveIng(Parent, Name, Module, HibernateAfterTimeout, Debug, Timers, NewState, false);
receiveIng(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, NewState, false);
{reply, Reply, NewState} -> {reply, Reply, NewState} ->
reply(From, Reply), reply(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} -> {mayReply, Reply, NewState} ->
case From of case From of
false -> false ->
receiveIng(Parent, Name, Module, HibernateAfterTimeout, Debug, Timers, NewState, false);
receiveIng(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, NewState, false);
_ -> _ ->
greply(From, Reply), 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; end;
{noreply, NewState, Actions} -> {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} -> {stop, Reason, NewState} ->
terminate(exit, Reason, ?STACKTRACE(), Name, Module, Debug, Timers, NewState, {return, stop}); terminate(exit, Reason, ?STACKTRACE(), Name, Module, Debug, Timers, NewState, {return, stop});
{reply, Reply, NewState, Actions} -> {reply, Reply, NewState, Actions} ->
reply(From, Reply), reply(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} -> {mayReply, Reply, NewState, Actions} ->
case From of case From of
false -> 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), 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; end;
{stopReply, Reason, Reply, NewState} -> {stopReply, Reason, Reply, NewState} ->
NewDebug = ?SYS_DEBUG(Debug, Name, {out, Reply, From, NewState}),
?SYS_DEBUG(Debug, Name, {out, Reply, From, NewState}),
try 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 after
_ = reply(From, Reply) _ = reply(From, Reply)
end; end;
_AnyRet -> _AnyRet ->
case IsAnyRet of case IsAnyRet of
true -> 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
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 case Result of
kpS -> kpS ->
loopEntry(Parent, Name, Module, HibernateAfterTimeout, Debug, Timers, CurState, LeftAction);
loopEntry(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, CurState, LeftAction);
{noreply, NewState} -> {noreply, NewState} ->
loopEntry(Parent, Name, Module, HibernateAfterTimeout, Debug, Timers, NewState, LeftAction);
loopEntry(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, NewState, LeftAction);
{noreply, NewState, Actions} -> {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} -> {stop, Reason, NewState} ->
terminate(exit, Reason, ?STACKTRACE(), Name, Module, Debug, Timers, NewState, {return, stop_reply}) terminate(exit, Reason, ?STACKTRACE(), Name, Module, Debug, Timers, NewState, {return, stop_reply})
end. end.
@ -902,8 +913,8 @@ doParseAL([OneAction | LeftActions], Name, Debug, IsHib, DoAfter, Timers) ->
doParseAL(LeftActions, Name, Debug, IsHib, DoAfter, Timers); doParseAL(LeftActions, Name, Debug, IsHib, DoAfter, Timers);
Timeout when is_integer(Timeout) -> Timeout when is_integer(Timeout) ->
erlang:send_after(Timeout, self(), 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}} {error, {bad_ActionType, OneAction}}
end. end.
@ -919,7 +930,28 @@ listHib(false) ->
listHib(_) -> listHib(_) ->
[hibernate]. [hibernate].
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% timer deal end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 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. %%% Terminate the server.
@ -998,6 +1030,22 @@ error_info(Reason, Name, From, Msg, Module, Debug, State) ->
}), }),
ok. ok.
error_msg(Reason, Name, From, Msg, Module, Debug, State) ->
Log = sys:get_log(Debug),
?LOG_ERROR(#{label => {gen_mpp, 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_mpp:format_log/2,
error_logger => #{tag => error, report_cb => fun gen_mpp:format_log/1}
}),
ok.
client_stacktrace(undefined) -> client_stacktrace(undefined) ->
undefined; undefined;
client_stacktrace({From, _Tag}) -> client_stacktrace({From, _Tag}) ->

+ 2
- 1
src/gen_srv.erl Просмотреть файл

@ -276,7 +276,7 @@ wakeupFromHib(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timer
loopEntry(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, CurState, Actions) -> loopEntry(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, CurState, Actions) ->
case doParseAL(Actions, Name, Debug, false, false, Timers) of case doParseAL(Actions, Name, Debug, false, false, Timers) of
{error, ErrorContent} -> {error, ErrorContent} ->
innerError(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, CurState, Actions, error, ErrorContent, []);
innerError(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, CurState, Actions, error, ErrorContent, ?STACKTRACE());
{Debug, IsHib, DoAfter, NewTimers} -> {Debug, IsHib, DoAfter, NewTimers} ->
case DoAfter of case DoAfter of
{doAfter, Args} -> {doAfter, Args} ->
@ -747,6 +747,7 @@ matchCallMsg(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers
throw:Result -> throw:Result ->
handleCR(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, CurState, Result, From, false); handleCR(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, CurState, Result, From, false);
Class:Reason:Strace -> Class:Reason:Strace ->
try_greply(From, {error, {inner_error, {Class, Reason, Strace}}}),
innerError(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, CurState, {{call, From}, Request}, Class, Reason, Strace) innerError(Parent, Name, Module, GbhOpts, HibernateAfterTimeout, Debug, Timers, CurState, {{call, From}, Request}, Class, Reason, Strace)
end. end.

Загрузка…
Отмена
Сохранить