-module(agAgencyUtils). -include("agVstCli.hrl"). -compile(inline). -compile({inline_size, 128}). -export([ cancelTimer/1 , dealClose/3 , reconnectTimer/2 , agencyReply/2 , agencyReply/4 , initReconnectState/3 , resetReconnectState/1 , updateReconnectState/1 ]). -spec dealClose(srvState(), cliState(), term()) -> {ok, srvState(), cliState()}. dealClose(SrvState, #cliState{requestsIns = RequestsIns, requestsOuts = RequestsOuts, curInfo = CurInfo} = ClientState, Reply) -> agencyReply(CurInfo, Reply), agencyReplyAll(RequestsOuts, RequestsIns, Reply), reconnectTimer(SrvState, ClientState#cliState{requestsIns = [], requestsOuts = [], backlogNum = 0, revStatus = leisure, curInfo = undefined, recvState = undefined}). -spec reconnectTimer(srvState(), cliState()) -> {ok, srvState(), cliState()}. reconnectTimer(#srvState{reconnectState = undefined} = SrvState, CliState) -> {ok, {SrvState#srvState{socket = undefined}, CliState}}; reconnectTimer(#srvState{reconnectState = ReconnectState} = SrvState, CliState) -> #reConnState{current = Current} = MewReconnectState = agAgencyUtils:updateReconnectState(ReconnectState), TimerRef = erlang:send_after(Current, self(), ?AgMDoNetConn), {ok, SrvState#srvState{reconnectState = MewReconnectState, socket = undefined, timerRef = TimerRef}, CliState}. -spec agencyReply(term(), term()) -> ok. agencyReply({undefined, _RequestId, TimerRef}, _Reply) -> agAgencyUtils:cancelTimer(TimerRef); agencyReply({PidForm, RequestId, TimerRef}, Reply) -> agAgencyUtils:cancelTimer(TimerRef), catch PidForm ! #agReqRet{messageId = RequestId, reply = Reply}, ok; agencyReply(undefined, _RequestRet) -> ok. -spec agencyReply(undefined | pid(), messageId(), undefined | reference(), term()) -> ok. agencyReply(undefined, MessageId, TimerRef, _Reply) -> agAgencyUtils:cancelTimer(TimerRef); agencyReply(FormPid, RequestId, TimerRef, Reply) -> agAgencyUtils:cancelTimer(TimerRef), catch FormPid ! #agReqRet{messageId = RequestId, reply = Reply}, ok. -spec agencyReplyAll(list(), list(), term()) -> ok. agencyReplyAll(RequestsOuts, RequestsIns, Reply) -> [agencyReply(FormPid, RequestId, undefined, Reply) || #agReq{messageId = RequestId, fromPid = FormPid} <- RequestsOuts], [agencyReply(FormPid, RequestId, undefined, Reply) || #agReq{messageId = RequestId, fromPid = FormPid} <- lists:reverse(RequestsIns)], ok. -spec cancelTimer(undefined | reference()) -> ok. cancelTimer(undefined) -> ok; cancelTimer(TimerRef) -> case erlang:cancel_timer(TimerRef) of false -> receive {timeout, TimerRef, _Msg} -> %% discard the timeout msg ok after 0 -> ok end; _ -> %% Timer already run ok end. -spec initReconnectState(boolean(), pos_integer(), pos_integer()) -> reconnectState() | undefined. initReconnectState(IsReconnect, Min, Max) -> case IsReconnect of true -> #reConnState{min = Min, max = Max, current = Min}; false -> undefined end. -spec resetReconnectState(undefined | reconnectState()) -> reconnectState() | undefined. resetReconnectState(#reConnState{min = Min} = ReconnectState) -> ReconnectState#reConnState{current = Min}. -spec updateReconnectState(reconnectState()) -> reconnectState(). updateReconnectState(#reConnState{current = Current, max = Max} = ReconnectState) -> NewCurrent = Current + Current, ReconnectState#reConnState{current = minCur(NewCurrent, Max)}. minCur(A, B) when B >= A -> A; minCur(_, B) -> B.