etrap_server_impl.erl

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

ERL
1,740
字号
%%-----------------------------------------------------------%%% function : is_descendant_transaction%% Arguments: Self  - its own object reference.%%            State - Gen-Server State%%            Coordinator object reference%% Returns  : boolean%% Effect   :%%------------------------------------------------------------is_descendant_transaction(Self, {Env, Local}, Coordinator) ->    type_check(?tr_get_typeCheck(Env), ?tr_Coordinator,	       "Coordinator:is_descendant_transaction", Coordinator),    {reply,      lists:any(?tr_IS_MEMBER(Coordinator), [Self|?tr_get_parents(Env)]),      {Env, Local}}.%%-----------------------------------------------------------%%% function : is_top_level_transaction%% Arguments: Self  - its own object reference.%%            State - Gen-Server State%% Returns  : boolean%% Effect   :%%------------------------------------------------------------is_top_level_transaction(_Self, {Env, Local}) ->     case catch ?tr_get_parents(Env) of	[] ->	     {reply, true, {Env, Local}};	 _ ->	     {reply, false, {Env, Local}}     end.%%-----------------------------------------------------------%%% function : hash_transaction%% Arguments: Self  - its own object reference.%%            State - Gen-Server State%% Returns  : hash code%% Effect   : Returns a hash code for the transaction associated%%            with the target object.%%------------------------------------------------------------hash_transaction(Self, {Env, Local}) ->    {reply, corba_object:hash(Self, ?tr_get_hashMax(Env)), {Env, Local}}.%%-----------------------------------------------------------%%% function : hash_top_level_tran%% Arguments: Self  - its own object reference.%%            State - Gen-Server State%% Returns  : hash code%% Effect   : Returns a hash code for the top-level transaction %%            associated with the target object. Equals %%            hash_transaction if it's a top-level transaction.%%------------------------------------------------------------hash_top_level_tran(Self, {Env, Local}) ->    case ?tr_get_parents(Env) of	[] ->	    {reply, 	     corba_object:hash(Self, ?tr_get_hashMax(Env)), 	     {Env, Local}};	Ancestrors ->	    case catch corba_object:hash(lists:last(Ancestrors), 					 ?tr_get_hashMax(Env)) of		{'EXCEPTION', _E} -> 		    corba:raise(?tr_unavailable);		Hash ->		    {reply, Hash, {Env, Local}}	    end    end.%%-----------------------------------------------------------%%% function : register_resource%% Arguments: Self  - its own object reference.%%            State - Gen-Server State%%            Resource object reference%% Returns  : RecoveryCoordinator (can be used during recovery)%% Effect   : Registers the specified resource as as participant%%            in the transaction associated with the target object.%% Exception: Inactive - Is prepared or terminated.%%------------------------------------------------------------register_resource(Self, {Env, Local}, Resource) ->    type_check(?tr_get_typeCheck(Env), ?tr_Resource,	       "Coordinator:register_resource", Resource),    case ?etr_get_status(Local) of	'StatusActive' -> % ok to register the Resource.	    NewLocal = ?etr_add_member(Local, Resource),	    RecoveryCoord = corba:create_subobject_key(Self, ?tr_get_etrap(Env)),	    {reply, RecoveryCoord, {Env, NewLocal}, ?tr_get_timeout(Env)};	_-> % Not active anymore. New members not ok.	    corba:raise(?tr_inactive)    end.	%%-----------------------------------------------------------%%% function : register_subtran_aware%% Arguments: Self  - its own object reference.%%            State - Gen-Server State%%            SubTransactionAwareResource object reference%% Returns  : -%% Effect   : Registers the specified object such that it%%            will be notified when the subtransaction has %%            commited or rolled back.%%------------------------------------------------------------register_subtran_aware(Self, {Env, Local}, SubTrAwareResource) ->    case ?tr_get_parents(Env) of	[] ->	    corba:raise(?tr_NotSubtr);	_->	    type_check(?tr_get_typeCheck(Env), ?tr_SubtransactionAwareResource,		       "Coordinator:register_subtran_aware", SubTrAwareResource),	    NewL = ?etr_add_subAw(Local, SubTrAwareResource),	    {reply, ok, {Env, ?etr_set_self(NewL, Self)}, 	     ?tr_get_timeout(Env)}    end.%%-----------------------------------------------------------%%% function : register_synchronization%% Arguments: Self  - its own object reference.%%            State - Gen-Server State%%            Synchronization%% Returns  : -%% Effect   : %%------------------------------------------------------------register_synchronization(_Self, {_Env, _Local}, _Synchronization) ->    corba:raise(#'CosTransactions_SynchronizationUnavailable'{}).%register_synchronization(Self, {Env, Local}, Synchronization) ->%    type_check(?tr_get_typeCheck(Env), ?tr_Synchronization,%	       "Coordinator:register_synchronization", Synchronization),%    case ?etr_get_status(Local) of%	'StatusActive' ->%	    case catch ?tr_get_parents(Env) of%		[] ->%		    {reply, ok, {Env, ?etr_add_sync(Local, Synchronization)}, %		     ?tr_get_timeout(Env)};%		[Parent|_] ->%		    case catch 'ETraP_Server':register_synchronization(Parent, Self) of%			{'EXCEPTION', E} ->%			    corba:raise(E);%			ok ->%			    {reply, ok, {Env, ?etr_add_sync(Local, Synchronization)}, %			     ?tr_get_timeout(Env)};%			What ->%			    corba:raise(#'COMM_FAILURE'{completion_status=?COMPLETED_MAYBE})%		    end%	    end;%	_ ->%	    corba:raise(?tr_inactive)%    end.%%-----------------------------------------------------------%%% function : rollback_only%% Arguments: Self  - its own object reference.%%            State - Gen-Server State%% Returns  : -%% Effect   : The transaction associated with the target object%%            is modified so that rollback IS the result.%%------------------------------------------------------------rollback_only(Self, {Env, Local}) ->    case ?etr_get_status(Local) of	'StatusActive' ->	    NewL = ?etr_set_status(Local, 'StatusRolledBack'),	    NewEnv = ?tr_set_rollback(Env, true),	    ?etr_log(?tr_get_etrap(Env),{rollback, NewL}),	    send_info(?etr_get_members(NewL), 'CosTransactions_Resource', rollback),	    notify_subtrAware(rollback, ?etr_get_subAw(NewL), Self),	    {stop, normal, ok, {NewEnv, NewL}};%% Replace the reply above if allow synchronization%	    case ?etr_get_sync(Local) of%		[] ->%		    {stop, normal, ok, {NewEnv, NewL}};%		_ ->%		    {reply, ok, {NewEnv, NewL}}%	    end;	_ ->	    corba:raise(?tr_inactive)    end.%%-----------------------------------------------------------%%% function : get_transaction_name%% Arguments: Self  - its own object reference.%%            State - Gen-Server State%% Returns  : string - which describes the transaction associated %%                     with the target object.%% Effect   : Intended for debugging.%%------------------------------------------------------------get_transaction_name(_Self, {Env, Local}) ->    {reply, ?tr_get_etrap(Env), {Env, Local}}.%%-----------------------------------------------------------%%% function : create_subtransaction%% Arguments: Self  - its own object reference.%%            State - Gen-Server State%% Returns  : A control object if subtransactions are allowed,%%            otherwise an exception is raised.%% Effect   : A new subtransaction is created whos parent is%%            the transaction associated with the target object.%% Exception: SubtransactionUnavailabe - no support for nested%%                                       transactions.%%            Inactive - already been prepared.%%------------------------------------------------------------create_subtransaction(Self, {Env, Local}) ->    case ?etr_get_status(Local) of	'StatusActive' ->	    case ?tr_get_subTraOK(Env) of		true ->		    ETraPName = 'ETraP_Common':create_name("subc"),		    Tname   = 'ETraP_Common':create_name("subt"),		    		    %% Create context for the new object.		    State   = ?tr_create_context(ETraPName, Tname, 						 ?tr_get_typeCheck(Env), 						 ?tr_get_hashMax(Env), 						 ?tr_get_subTraOK(Env),						 ?tr_get_maxR(Env),						 ?tr_get_maxW(Env)),		    State2  = ?tr_add_parent(State, Self),		    		    State3  = ?tr_set_alarm(State2, ?tr_get_alarm(Env)),		    State4  = ?tr_set_timeout(State3, ?tr_get_timeout(Env)),		    Control = ?tr_start_child(?SUP_ETRAP(State4)),		    %% Set the SubCoordinator object reference and register it as participant.		    SubCoord = 'CosTransactions_Control':get_coordinator(Control),		    NewLocal = ?etr_add_member(Local, SubCoord),		    {reply, Control, {Env, NewLocal}, ?tr_get_timeout(Env)};		_ ->		    %% subtransactions not allowed, raise exception.		    corba:raise(?tr_subunavailable)	    end;	_->	    corba:raise(?tr_inactive)    end.%%-----------------------------------------------------------%%% function : get_txcontext%% Arguments: %% Returns  : PropagationContext%% Effect   : %%------------------------------------------------------------get_txcontext(_Self, {_Env, _Local}) ->    corba:raise(#'CosTransactions_Unavailable'{}).%get_txcontext(Self, {Env, Local}) ->%    Otid = #'CosTransactions_otid_t'{formatID=0, %				     bqual_length=0, %				     tid=[corba_object:hash(Self, %							   ?tr_get_hashMax(Env))]},%    TrIDs = create_TransIdentities(?tr_get_parents(Env), Env, [], Otid),%    C=case ?tr_get_parents(Env) of%	  [] ->%	      #'CosTransactions_TransIdentity'{coord=Self, %					       term=?tr_get_terminator(Env), %					       otid=Otid};%	  _->%	      #'CosTransactions_TransIdentity'{coord=Self, %					       term=?tr_NIL_OBJ_REF, %					       otid=Otid}%      end,%    case ?tr_get_timeout(Env) of%	infinity ->%	    #'CosTransactions_PropagationContext'{timeout=0, %						  current= C, %						  parents=TrIDs};%	T ->%	    #'CosTransactions_PropagationContext'{timeout=T/1000, %						  current= C, %						  parents=TrIDs}%    end.%create_TransIdentities([], _, Parents, _) -> Parents;%create_TransIdentities([Phead|Ptail], Env, Parents, Otid) ->%    NO=Otid#'CosTransactions_TransIdentity'{otid=%					    corba_object:hash(Phead, %							      ?tr_get_hashMax(Env))},%    create_TransIdentities([Phead|Ptail], Env, Parents++%			   [#'CosTransactions_TransIdentity'{coord=Phead, %							     term=?tr_NIL_OBJ_REF, %							     otid=NO}], %			   Otid).%%--------- Inherit from CosTransactions::Synchronization ---%%-----------------------------------------------------------%%% function : before_completion%% Arguments: %% Returns  : %% Effect   : %%------------------------------------------------------------%before_completion(Self, {Env, Local}) ->%    send_info(?etr_get_sync(Local), %	      'CosTransactions_Synchronization', before_completion),%    {reply, ok, {Env, Local}}.%%-----------------------------------------------------------%%% function : after_completion%% Arguments: %% Returns  : %% Effect   : %%------------------------------------------------------------%after_completion(Self, {Env, Local}, Status) ->%    send_info(?etr_get_sync(Local), Status,%	      'CosTransactions_Synchronization', after_completion),%    {stop, normal, ok, {Env, Local}}.%%--------------- IMPLEMENTATION SPECIFIC -------------------%%-----------------------------------------------------------%%% function : start_object%% Arguments: %% Returns  : EXIT, EXCEPTION, or {ok, State}%% Effect   : used by init/1 only.%%------------------------------------------------------------start_object(Env)->    ?put_debug_data(self, Env),    Local = ?etr_get_init(Env),    LogName = ?tr_get_etrap(Env),    case catch file:read_file_info(LogName) of	{error, enoent} -> 	    %% File does not exist. It's the first time. No restart.	    ?debug_print("ETraP_Server:init(~p)~n",[?tr_get_etrap(Env)]),	    etrap_logmgr:start(LogName),	    {ok, 	     {Env, ?etr_set_status(Local, 'StatusActive')}, 	     ?tr_get_timeout(Env)};	{error, Reason} -> 	    %% File exist but error occurred.	    ?tr_error_msg("Control (~p) Cannot open log file: ~p~n",			  [LogName, Reason]),	    {stop, "unable_to_open_log"};	_ -> 

⌨️ 快捷键说明

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