-
-
Notifications
You must be signed in to change notification settings - Fork 36
/
CloudAPI.Ext.MethodLimits.pas
107 lines (90 loc) · 2.59 KB
/
CloudAPI.Ext.MethodLimits.pas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
unit CloudAPI.Ext.MethodLimits;
interface
uses
CloudAPI.Types,
System.Generics.Collections,
System.SysUtils;
type
TcaRequestLimitList = class(TList<TcaRequestLimit>);
TcaRequestLimitManager = class
private
FGlobal: TcaRequestLimitList;
FLocal: TcaRequestLimitList;
FOnLimit: TProc<Int64>;
protected
function CalculateWait(AList: TcaRequestLimitList; const AName: string = ''): Int64;
public
constructor Create;
procedure Add(const ALimit: Int64; const AName: string; const AIsGlobal: Boolean);
function GetGlobalLimits: TArray<TcaRequestLimit>;
function GetLocalLimits(const AName: string): TArray<TcaRequestLimit>;
function GetLimits(const AName: string): TArray<TcaRequestLimit>;
function GlobalWait: Int64;
function LocalWait(const AName: string): Int64;
destructor Destroy; override;
property OnLimit: TProc<Int64> read FOnLimit write FOnLimit;
end;
implementation
{ TcaRequestLimitManager }
procedure TcaRequestLimitManager.Add(const ALimit: Int64; const AName: string; const AIsGlobal: Boolean);
var
LLimit: TcaRequestLimit;
begin
LLimit := TcaRequestLimit.Create(ALimit, AName, AIsGlobal);
if AIsGlobal then
FGlobal.Add(LLimit)
else
FLocal.Add(LLimit);
end;
function TcaRequestLimitManager.CalculateWait(AList: TcaRequestLimitList; const AName: string = ''): Int64;
var
I: Integer;
begin
Result := 0;
for I := AList.Count - 1 downto 0 do
begin
if AList.Count = 0 then
break;
if AList[I].IsExpired then
AList.Delete(I)
else if AList[I].Name.Contains(AName) then
Inc(Result, AList[I].ActualLimit);
end;
end;
constructor TcaRequestLimitManager.Create;
begin
inherited Create;
FGlobal := TcaRequestLimitList.Create;
FLocal := TcaRequestLimitList.Create;
end;
destructor TcaRequestLimitManager.Destroy;
begin
FGlobal.Free;
FLocal.Free;
inherited Destroy;
end;
function TcaRequestLimitManager.GetGlobalLimits: TArray<TcaRequestLimit>;
begin
CalculateWait(FGlobal, '');
Result := FGlobal.ToArray;
end;
function TcaRequestLimitManager.GetLimits(const AName: string): TArray<TcaRequestLimit>;
begin
CalculateWait(FGlobal, '');
CalculateWait(FLocal, '');
Result := FLocal.ToArray;
end;
function TcaRequestLimitManager.GetLocalLimits(const AName: string): TArray<TcaRequestLimit>;
begin
CalculateWait(FLocal, AName);
Result := FLocal.ToArray;
end;
function TcaRequestLimitManager.GlobalWait: Int64;
begin
Result := CalculateWait(FGlobal);
end;
function TcaRequestLimitManager.LocalWait(const AName: string): Int64;
begin
Result := GlobalWait + CalculateWait(FLocal, AName);
end;
end.