Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 

117 lignes
3.9 KiB

-module(agAgencyUtils).
-include("agHttpCli.hrl").
-compile(inline).
-compile({inline_size, 128}).
-export([
getQueue/1
, addQueue/2
, delQueue/1
, clearQueue/0
, cancelTimer/1
, dealClose/3
, reconnectTimer/2
, agencyReply/2
, agencyReply/4
, initReconnectState/3
, resetReconnectState/1
, updateReconnectState/1
]).
-spec getQueue(pos_integer()) -> undefined | miRequest().
getQueue(RequestsIn) ->
erlang:get(RequestsIn).
-spec addQueue(pos_integer(), miRequest()) -> undefined.
addQueue(RequestsIn, MiRequest) ->
erlang:put(RequestsIn, MiRequest).
-spec delQueue(pos_integer()) -> miRequest().
delQueue(RequestsIn) ->
erlang:erase(RequestsIn).
-spec clearQueue() -> term().
clearQueue() ->
erlang:erase().
-spec dealClose(srvState(), cliState(), term()) -> {ok, srvState(), cliState()}.
dealClose(SrvState, #cliState{curInfo = CurInfo} = ClientState, Reply) ->
agencyReply(CurInfo, Reply),
agencyReplyAll(Reply),
reconnectTimer(SrvState, ClientState#cliState{requestsIn = 1, requestsOut = 0, backlogNum = 0, status = 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) ->
#reconnectState{current = Current} = MewReconnectState = agAgencyUtils:updateReconnectState(ReconnectState),
TimerRef = erlang:send_after(Current, self(), ?miDoNetConnect),
{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 ! #miRequestRet{requestId = RequestId, reply = Reply},
ok;
agencyReply(undefined, _RequestRet) ->
ok.
-spec agencyReply(undefined | pid(), requestId(), undefined | reference(), term()) -> ok.
agencyReply(undefined, _RequestId, TimerRef, _Reply) ->
agAgencyUtils:cancelTimer(TimerRef),
ok;
agencyReply(FormPid, RequestId, TimerRef, Reply) ->
agAgencyUtils:cancelTimer(TimerRef),
catch FormPid ! #miRequestRet{requestId = RequestId, reply = Reply},
ok.
-spec agencyReplyAll(term()) -> ok.
agencyReplyAll(Reply) ->
AllList = agAgencyUtils:clearQueue(),
[agencyReply(FormPid, RequestId, undefined, Reply) || #miRequest{requestId = RequestId, fromPid = FormPid} <- AllList],
ok.
-spec cancelTimer(undefined | reference()) -> ok.
cancelTimer(undefined) -> ok;
cancelTimer(TimerRef) ->
case erlang:cancel_timer(TimerRef) of
false ->
%% 找不到计时器,我们还没有看到超时消息
receive
{timeout, TimerRef, _Msg} ->
%% 丢弃该超时消息
ok
after 0 ->
ok
end;
_ ->
%% Timer 已经运行了
ok
end.
-spec initReconnectState(boolean(), pos_integer(), pos_integer()) -> reconnectState() | undefined.
initReconnectState(IsReconnect, Min, Max) ->
case IsReconnect of
true ->
#reconnectState{min = Min, max = Max, current = Min};
false ->
undefined
end.
-spec resetReconnectState(undefined | reconnectState()) -> reconnectState() | undefined.
resetReconnectState(#reconnectState{min = Min} = ReconnectState) ->
ReconnectState#reconnectState{current = Min}.
-spec updateReconnectState(reconnectState()) -> reconnectState().
updateReconnectState(#reconnectState{current = Current, max = Max} = ReconnectState) ->
NewCurrent = Current + Current,
ReconnectState#reconnectState{current = minCur(NewCurrent, Max)}.
minCur(A, B) when B >= A ->
A;
minCur(_, B) ->
B.