|
-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.
|
|
|