mirror of
https://github.com/processone/ejabberd.git
synced 2024-12-26 17:38:45 +01:00
Allow customizing the StateData in p1_fsm before error reporting.
A new callback is introduced on the p1_fsm behaviour:
print_error/1
If the module implements this function, it will be invoked
in case of process crash with the current state data *before*
printing the error in the log. The function must return the
desired State to print.
It is used in ejabberd_c2s to prune the presence sets that
can be large. Instead, the state is changed to include only
the # of elements on each set.
Change inspired in comming changes to gen_server on OTP, and
b01d15abc3 (diff-0)
This commit is contained in:
parent
44b282474a
commit
41aa693896
@ -55,7 +55,9 @@
|
|||||||
handle_sync_event/4,
|
handle_sync_event/4,
|
||||||
code_change/4,
|
code_change/4,
|
||||||
handle_info/3,
|
handle_info/3,
|
||||||
terminate/3]).
|
terminate/3,
|
||||||
|
print_state/1
|
||||||
|
]).
|
||||||
|
|
||||||
-include("ejabberd.hrl").
|
-include("ejabberd.hrl").
|
||||||
-include("jlib.hrl").
|
-include("jlib.hrl").
|
||||||
@ -1334,6 +1336,19 @@ handle_info(Info, StateName, StateData) ->
|
|||||||
?ERROR_MSG("Unexpected info: ~p", [Info]),
|
?ERROR_MSG("Unexpected info: ~p", [Info]),
|
||||||
fsm_next_state(StateName, StateData).
|
fsm_next_state(StateName, StateData).
|
||||||
|
|
||||||
|
|
||||||
|
%%----------------------------------------------------------------------
|
||||||
|
%% Func: print_state/1
|
||||||
|
%% Purpose: Prepare the state to be printed on error log
|
||||||
|
%% Returns: State to print
|
||||||
|
%%----------------------------------------------------------------------
|
||||||
|
print_state(State = #state{pres_t = T, pres_f = F, pres_a = A, pres_i = I}) ->
|
||||||
|
State#state{pres_t = {pres_t, ?SETS:size(T)},
|
||||||
|
pres_f = {pres_f, ?SETS:size(F)},
|
||||||
|
pres_a = {pres_a, ?SETS:size(A)},
|
||||||
|
pres_i = {pres_i, ?SETS:size(I)}
|
||||||
|
}.
|
||||||
|
|
||||||
%%----------------------------------------------------------------------
|
%%----------------------------------------------------------------------
|
||||||
%% Func: terminate/3
|
%% Func: terminate/3
|
||||||
%% Purpose: Shutdown the fsm
|
%% Purpose: Shutdown the fsm
|
||||||
|
@ -25,7 +25,8 @@
|
|||||||
%% - You can limit the time processing a message (TODO): If the
|
%% - You can limit the time processing a message (TODO): If the
|
||||||
%% message processing does not return in a given period of time, the
|
%% message processing does not return in a given period of time, the
|
||||||
%% process will be terminated.
|
%% process will be terminated.
|
||||||
%%
|
%% - You might customize the State data before sending it to error_logger
|
||||||
|
%% in case of a crash (just export the function print_state/1)
|
||||||
%% $Id$
|
%% $Id$
|
||||||
%%
|
%%
|
||||||
-module(p1_fsm).
|
-module(p1_fsm).
|
||||||
@ -146,7 +147,7 @@
|
|||||||
|
|
||||||
behaviour_info(callbacks) ->
|
behaviour_info(callbacks) ->
|
||||||
[{init,1},{handle_event,3},{handle_sync_event,4},{handle_info,3},
|
[{init,1},{handle_event,3},{handle_sync_event,4},{handle_info,3},
|
||||||
{terminate,3},{code_change,4}];
|
{terminate,3},{code_change,4}, {print_state,1}];
|
||||||
behaviour_info(_Other) ->
|
behaviour_info(_Other) ->
|
||||||
undefined.
|
undefined.
|
||||||
|
|
||||||
@ -376,7 +377,7 @@ loop(Parent, Name, StateName, StateData, Mod, hibernate, Debug,
|
|||||||
Debug, Limits, Queue1, QueueLen - 1, false);
|
Debug, Limits, Queue1, QueueLen - 1, false);
|
||||||
{empty, _} ->
|
{empty, _} ->
|
||||||
Reason = internal_queue_error,
|
Reason = internal_queue_error,
|
||||||
error_info(Reason, Name, hibernate, StateName, StateData, Debug),
|
error_info(Mod, Reason, Name, hibernate, StateName, StateData, Debug),
|
||||||
exit(Reason)
|
exit(Reason)
|
||||||
end;
|
end;
|
||||||
loop(Parent, Name, StateName, StateData, Mod, hibernate, Debug,
|
loop(Parent, Name, StateName, StateData, Mod, hibernate, Debug,
|
||||||
@ -620,7 +621,7 @@ reply(Name, {To, Tag}, Reply, Debug, StateName) ->
|
|||||||
terminate(Reason, Name, Msg, Mod, StateName, StateData, Debug) ->
|
terminate(Reason, Name, Msg, Mod, StateName, StateData, Debug) ->
|
||||||
case catch Mod:terminate(Reason, StateName, StateData) of
|
case catch Mod:terminate(Reason, StateName, StateData) of
|
||||||
{'EXIT', R} ->
|
{'EXIT', R} ->
|
||||||
error_info(R, Name, Msg, StateName, StateData, Debug),
|
error_info(Mod, R, Name, Msg, StateName, StateData, Debug),
|
||||||
exit(R);
|
exit(R);
|
||||||
_ ->
|
_ ->
|
||||||
case Reason of
|
case Reason of
|
||||||
@ -639,12 +640,12 @@ terminate(Reason, Name, Msg, Mod, StateName, StateData, Debug) ->
|
|||||||
[self(), Limit]),
|
[self(), Limit]),
|
||||||
exit(shutdown);
|
exit(shutdown);
|
||||||
_ ->
|
_ ->
|
||||||
error_info(Reason, Name, Msg, StateName, StateData, Debug),
|
error_info(Mod, Reason, Name, Msg, StateName, StateData, Debug),
|
||||||
exit(Reason)
|
exit(Reason)
|
||||||
end
|
end
|
||||||
end.
|
end.
|
||||||
|
|
||||||
error_info(Reason, Name, Msg, StateName, StateData, Debug) ->
|
error_info(Mod, Reason, Name, Msg, StateName, StateData, Debug) ->
|
||||||
Reason1 =
|
Reason1 =
|
||||||
case Reason of
|
case Reason of
|
||||||
{undef,[{M,F,A}|MFAs]} ->
|
{undef,[{M,F,A}|MFAs]} ->
|
||||||
@ -662,12 +663,16 @@ error_info(Reason, Name, Msg, StateName, StateData, Debug) ->
|
|||||||
_ ->
|
_ ->
|
||||||
Reason
|
Reason
|
||||||
end,
|
end,
|
||||||
|
StateToPrint = case erlang:function_exported(Mod, print_state, 1) of
|
||||||
|
true -> (catch Mod:print_state(StateData));
|
||||||
|
false -> StateData
|
||||||
|
end,
|
||||||
Str = "** State machine ~p terminating \n" ++
|
Str = "** State machine ~p terminating \n" ++
|
||||||
get_msg_str(Msg) ++
|
get_msg_str(Msg) ++
|
||||||
"** When State == ~p~n"
|
"** When State == ~p~n"
|
||||||
"** Data == ~p~n"
|
"** Data == ~p~n"
|
||||||
"** Reason for termination = ~n** ~p~n",
|
"** Reason for termination = ~n** ~p~n",
|
||||||
format(Str, [Name, get_msg(Msg), StateName, StateData, Reason1]),
|
format(Str, [Name, get_msg(Msg), StateName, StateToPrint, Reason1]),
|
||||||
sys:print_log(Debug),
|
sys:print_log(Debug),
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user