etrap_server_impl.erl

来自「OTP是开放电信平台的简称」· ERL 代码 · 共 1,740 行 · 第 1/5 页

ERL
1,740
字号
    %%-----------------------------------------------------------%%% function : evaluate_answer%% Arguments: %% Returns  : %% Effect   : Check what kind of exception we received.%%------------------------------------------------------------evaluate_answer(E, Rhead, _Vote, Exc, Log, Local)   when record(E, 'CosTransactions_HeuristicMixed') ->    ?etr_log(Log, {heuristic, {Rhead, E}}),    {Exc#exc{mixed = true}, ?etr_add_raisedH(Local, Rhead), []};evaluate_answer(E, Rhead, _Vote, Exc, Log, Local)  when record(E, 'CosTransactions_HeuristicHazard') ->    ?etr_log(Log, {heuristic, {Rhead, E}}),    {Exc#exc{hazard = true}, ?etr_add_raisedH(Local, Rhead), []};evaluate_answer(E, Rhead, Vote, Exc, Log, Local)  when record(E, 'CosTransactions_HeuristicCommit') ->    case Vote of	commit ->	    ?etr_log(Log, {heuristic, {Rhead, E}}),	    {Exc, ?etr_add_raisedH(Local, Rhead), []};	_->	    ?etr_log(Log, {heuristic, {Rhead, ?tr_mixed}}),	    {Exc#exc{mixed = true}, ?etr_add_raisedH(Local, Rhead), []}    end;evaluate_answer(E, Rhead, Vote, Exc, Log, Local)   when record(E, 'CosTransactions_HeuristicRollback')->    case Vote of	rollback ->	    ?etr_log(Log, {heuristic, {Rhead, ?tr_rollback}}),	    {Exc, ?etr_add_raisedH(Local, Rhead), []};	_->	    ?etr_log(Log, {heuristic, {Rhead, ?tr_mixed}}),	    {Exc#exc{mixed = true}, ?etr_add_raisedH(Local, Rhead), []}    end;evaluate_answer(E, Rhead, Vote, Exc, Log, Local)   when Vote == commit, record(E, 'TRANSACTION_ROLLEDBACK') ->    ?etr_log(Log, {heuristic, {Rhead, ?tr_mixed}}),    {Exc#exc{mixed = true}, ?etr_add_raisedH(Local, Rhead), []};evaluate_answer(E, Rhead, Vote, Exc, Log, Local) when record(E, 'TIMEOUT') ->    ?tr_error_msg("Coordinator:~p( ~p ) Object unreachable.~nReason: ~p~n",		  [Vote, Rhead, E]),    case catch corba_object:non_existent(Rhead) of	true ->	    %% Since we have presumed abort, the child will	    %% assume rollback if this server do not exist any more.	    ?etr_log(Log, {heuristic, {Rhead, ?tr_hazard}}),	    {Exc#exc{hazard = true}, Local, []};	_ ->	    {Exc, Local, [Rhead]}    end;evaluate_answer(E, Rhead, Vote, Exc, Log, Local) when record(E, 'TRANSIENT') ->    ?tr_error_msg("Coordinator:~p( ~p ) Object unreachable.~nReason: ~p~n",		  [Vote, Rhead, E]),    case catch corba_object:non_existent(Rhead) of	true ->	    %% Since we have presumed abort, the child will	    %% assume rollback if this server do not exist any more.	    ?etr_log(Log, {heuristic, {Rhead, ?tr_hazard}}),	    {Exc#exc{hazard = true}, Local, []};	_ ->	    {Exc, Local, [Rhead]}    end;evaluate_answer(E, Rhead, Vote, Exc, Log, Local) when record(E, 'COMM_FAILURE') ->    ?tr_error_msg("Coordinator:~p( ~p ) Object unreachable.~nReason: ~p~n",		  [Vote, Rhead, E]),    case catch corba_object:non_existent(Rhead) of	true ->	    %% Since we have presumed abort, the child will	    %% assume rollback if this server do not exist any more.	    ?etr_log(Log, {heuristic, {Rhead, ?tr_hazard}}),	    {Exc#exc{hazard = true}, Local, []};	_ ->	    {Exc, Local, [Rhead]}    end;evaluate_answer(E, Rhead, Vote, Exc, Log, Local)when record(E, 'OBJECT_NOT_EXIST') ->    ?tr_error_msg("Coordinator:~p( ~p ) Object unreachable.~nReason: ~p~n",		  [Vote, Rhead, E]),    %% Since we have presumed abort, the child will    %% assume rollback if this server do not exist any more.    ?etr_log(Log, {heuristic, {Rhead, ?tr_hazard}}),    {Exc#exc{hazard = true}, Local, []};evaluate_answer(Unknown, Rhead, Vote, Exc, _Log, Local)->    ?tr_error_msg("Coordinator:~p( ~p ). Unknown reply: ~p.~n", 		  [Vote, Rhead, Unknown]),    {Exc, Local, []}.%%-----------------------------------------------------------%%% function : test_exc%% Arguments: Exc   - instance of #exc{} locally declared.%%            Vote  - 'rollback' or 'commit'%%            Reply - If no exceptions this is the default reply.%%            State - genserver state%% Returns  : %% Effect   : Raise the correct exception or simply reply to%%            the genserver. NOTE that the testing for exceptions%%            differs if we are performing a rollback or commit.%%            Check if Mixed first; takes priority over Hazard.%%            HeuristicRollback and VoteCommit together give %%            HeuristicMixed%%            HeuristicCommit and VoteRollback together give%%            HeuristicMixed%%------------------------------------------------------------test_exc(#exc{mixed = true}, _, _, {Env, Local}) ->    {reply, {'EXCEPTION', ?tr_mixed}, {Env, ?etr_set_exc(Local, ?tr_mixed)}};% Left out for now to avoid dialyzer warning.%test_exc(#exc{rollback = true}, commit, _, {Env, Local}) ->%    {reply, {'EXCEPTION', ?tr_mixed}, {Env, ?etr_set_exc(Local, ?tr_mixed)}};% Left out for now to avoid dialyzer warning.%test_exc(#exc{commit = true}, rollback, _, {Env, Local}) ->%    {reply, {'EXCEPTION', ?tr_mixed}, {Env, ?etr_set_exc(Local, ?tr_mixed)}};test_exc(#exc{hazard = true}, _, _, {Env, Local}) ->    {reply, {'EXCEPTION', ?tr_hazard}, {Env, ?etr_set_exc(Local, ?tr_hazard)}};test_exc(_, _, {'EXCEPTION', E}, {Env, Local})   when record(E, 'TRANSACTION_ROLLEDBACK')->    {stop, normal, {'EXCEPTION', E}, {Env, Local}};%% Replace the case above if allow synchronization%test_exc(_, _, {'EXCEPTION', E}, {Env, Local}) %  when record(E, 'TRANSACTION_ROLLEDBACK')->%    case ?etr_get_sync(Local) of%	[] ->%	    {stop, normal, {'EXCEPTION', E}, {Env, Local}};%	_->%	    {reply, {'EXCEPTION', E}, {Env, Local}}%    end;test_exc(_, _, {'EXCEPTION', E}, State) ->    {reply, {'EXCEPTION', E}, State};test_exc(_, _, Reply, {Env, Local}) ->    {stop, normal, Reply, {Env, Local}}.%% Replace the case above if allow synchronization%test_exc(_, _, Reply, {Env, Local}) ->%    case ?etr_get_sync(Local) of%	[] ->%	    {stop, normal, Reply, {Env, Local}};%	_ ->%	    {reply, Reply, {Env, Local}}%    end.	%%-----------------------------------------------------------%%% function : evaluate_status%% Arguments: %% Returns  : %% Effect   : %%------------------------------------------------------------evaluate_status(Status) -> case Status of     'StatusCommitted'      -> commit;     'StatusCommitting'     -> commit;     'StatusMarkedRollback' -> rollback;     'StatusRollingBack'    -> rollback;     'StatusRolledBack'     -> rollback;     'StatusActive'         -> rollback;     'StatusPrepared'       -> rollback;     'StatusUnknown'        -> rollback;     'StatusNoTransaction'  -> rollback;     'StatusPreparing'      -> rollback;     _-> rollback end.%%-----------------------------------------------------------%%% function : prepare_restart%% Arguments: %% Returns  : %% Effect   : %%------------------------------------------------------------%% The file contains no data. The coordinator crashed before%% a prepare-call was made. Presumed rollback.prepare_restart(State, eof) ->     ?debug_print("prepare_restart: eof, init~n",[]),    self() ! {suicide, self()},    {ok, State};%% Collected all necessary votes. Do commit_restart.prepare_restart({Env, _}, {{pre_vote, _Vote, Data}, Cursor}) ->    ?debug_print("prepare_restart: pre_vote( ~p )~n",[_Vote]),    if	?tr_is_root(Env) ->	    commit_restart({Env, Data}, 			   ?etr_read(?tr_get_etrap(Env), Cursor), root);	true ->		    commit_restart({Env, Data}, 			   ?etr_read(?tr_get_etrap(Env), Cursor), subCoord)    end;%% 'rollback' called without 'prepare'. This case occurs if the Coordinator%% crashes when send_info or notify_subtrAware.prepare_restart({Env, _}, {{rollback, NewL}, _Cursor}) ->    ?debug_print("prepare_restart: pre_vote( rollback )~n",[]),    send_info(?etr_get_members(NewL), 'CosTransactions_Resource', rollback),    notify_subtrAware(rollback, ?etr_get_subAw(NewL), ?etr_get_self(NewL)),    self() ! {suicide, self()},    {ok, {Env, NewL}};%% Something is wrong in the log.prepare_restart(_, _) ->    ?tr_error_msg("Internal log read failed:~n", []),    {stop, {error, "restart failed"}}.%%-----------------------------------------------------------%%% function : commit_restart%% Arguments: Env - server context%% Returns  : %% Effect   : %%------------------------------------------------------------commit_restart({Env, Local}, Data, Phase) ->    Exc = set_exception(#exc{}, ?etr_get_exc(Local)),    commit_restart({Env, Local}, Data, Phase, Exc).%% Normal case. No errors no exceptions.commit_restart({Env, Local}, {{sent, Obj}, Cursor}, Vote, Exc) ->    ?debug_print("commit_restart: sent~n",[]),    commit_restart({Env, ?etr_remove_vc(Local, Obj)}, 		   ?etr_read(?tr_get_etrap(Env), Cursor), Vote, Exc);commit_restart({Env, Local}, {{heuristic, {Obj,E}}, Cursor}, Vote, Exc) ->    ?debug_print("commit_restart: heuristic    ~p~n",[E]),    NewExc = set_exception(Exc, E),    commit_restart({Env, ?etr_add_raisedH(Local, Obj)},		   ?etr_read(?tr_get_etrap(Env), Cursor), Vote, NewExc);%% --- cases which only can occure once in the log ------------%% The file contains no data. The coordinator crashed before%% a decision was made. Causes rollback.commit_restart({E, L}, eof, root, Exc) ->     ?debug_print("commit_restart: eof init (root only)~n",[]),    {Env, Local} = send_decision({E, L}, no_reply, ?etr_get_vc(L), 				 rollback, Exc),    exception_set({Env, Local});%% Replace the reply above if allow synchronization%    case ?etr_get_sync(Local) of%	[] ->%	    exception_set({Env, Local});%	SynchObjs ->%	    {ok, {Env, Local}}%    end;%% Passed the prepare_restart. Not received a commit decision from the%% parent.commit_restart({E, L}, eof, subCoord, Exc) ->     ?debug_print("commit_restart: eof init (subcoord only)~n",[]),    case catch corba_object:non_existent(?tr_get_parent(E)) of	true ->	    %% Presumed rollback.	    {Env, Local} = send_decision({E, L}, no_reply, ?etr_get_vc(L), 					 rollback, Exc),	    self() ! {suicide, self()},	    {ok, {Env, Local}};%% Replace the reply above if allow synchronization%	    case ?etr_get_sync(Local) of%		[] ->%		    self() ! {suicide, self()},%		    {ok, {Env, Local}};%		SynchObjs ->%		    case ?tr_get_parents(Env) of%			[] ->%			    send_info(SynchObjs, ?etr_get_status(Local),%				      'CosTransactions_Synchronization', after_completion);%			_->%			    ok%		    end,%		    self() ! {suicide, self()},%		    {ok, {Env, Local}}%	    end;	_->	    {ok, {E, L}}    end;commit_restart({Env, Local}, eof, Vote, Exc) ->     ?debug_print("commit_restart: eof    VOTE: ~p~n",[Vote]),    case ?etr_get_vc(Local) of	[] ->	    ?debug_print("commit_restart: all sent, test exc~n",[]),            exception_set({Env, Local});	VC ->	    ?debug_print("commit_restart: note done. send more~n",[]),	    State = send_decision({Env, Local}, no_reply, VC, Vote, Exc),	    exception_set(State)    end;%% Decision made, i.e. rollback or commit.commit_restart({Env, Local}, {rollback, Cursor}, _Phase, Exc) ->    ?debug_print("commit_restart: decided rollback~n",[]),    commit_restart({Env, ?etr_set_status(Local, 'StatusRolledBack')}, 		   ?etr_read(?tr_get_etrap(Env), Cursor), rollback, Exc);commit_restart({Env, Local}, {commit, Cursor}, _Phase, Exc) ->    ?debug_print("commit_restart: decided commit~n",[]),    commit_restart({Env, ?etr_set_status(Local, 'StatusCommitted')}, 		   ?etr_read(?tr_get_etrap(Env), Cursor), commit, Exc);commit_restart({Env, Local}, {forget_phase, Cursor}, _, _) ->    ?debug_print("commit_restart: start sending forget~n",[]),    forget_restart({Env, Local}, ?etr_read(?tr_get_etrap(Env), Cursor));commit_restart({_Env, _Local}, _R, _, _) ->    ?debug_print("RESTART FAIL: ~p~n",[_R]),    ?tr_error_msg("Internal log read failed:~n", []),    exit("restart failed").%%-----------------------------------------------------------%%% function : forget_restart%% Arguments: {Env, Local} - server context%% Returns  : %% Effect   : %%------------------------------------------------------------%% Exception logged. Test if we issued a 'forget()' to the Resource.forget_restart({Env, Local}, eof) ->    case ?etr_get_raisedH(Local) of	[] ->	    ?debug_print("forget_restart: all done~n",[]);	Left ->	    ?debug_print("forget_restart: not done. send more~n",[]),	    send_forget(Left, ?tr_get_etrap(Env))    end,    self() ! {suicide, self()},    {ok, {Env, Local}};%% Replace the reply above if allow synchronization%    case ?etr_get_sync(Local) of%	[] ->%	    self() ! {suicide, self()},%	    {ok, {Env, Local}};%	SynchObjs ->%	    case ?tr_get_parents(Env) of%		[] ->%		    send_info(SynchObjs, ?etr_get_status(Local),%			      'CosTransactions_Synchronization', after_completion),%		    self() ! {suicide, self()},%		    {ok, {Env, Local}};%		_->%		    {ok, {Env, Local}}%	    end%    end;forget_restart({Env, Local}, {{forgotten, Obj}, Cursor}) ->    ?debug_print("forget_restart: forgotten  heuristic~n",[]),    NewL = ?etr_remove_raisedH(Local, Obj),    forget_restart({Env, NewL}, ?etr_read(?tr_get_etrap(Env), Cursor));forget_restart({Env, Local}, {{not_forgotten, Obj}, Cursor}) ->    ?debug_print("forget_restart: not_forgotten~n",[]),    NewL = ?etr_remove_raisedH(Local, Obj),    send_forget([Obj], dummy),    forget_restart({Env, NewL}, ?etr_read(?tr_get_etrap(Env), Cursor)).%%--------------- END OF MODULE ------------------------------

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?