@quenty/aggregator 1.4.2 → 1.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/package.json +9 -9
- package/src/Shared/Aggregator.lua +29 -15
- package/src/Shared/RateAggregator.lua +30 -8
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,14 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [1.4.3](https://github.com/Quenty/NevermoreEngine/compare/@quenty/aggregator@1.4.2...@quenty/aggregator@1.4.3) (2025-04-10)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @quenty/aggregator
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
6
14
|
## [1.4.2](https://github.com/Quenty/NevermoreEngine/compare/@quenty/aggregator@1.4.0...@quenty/aggregator@1.4.2) (2025-04-07)
|
|
7
15
|
|
|
8
16
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quenty/aggregator",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.3",
|
|
4
4
|
"description": "Aggregates async promise requests",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Roblox",
|
|
@@ -25,16 +25,16 @@
|
|
|
25
25
|
"Quenty"
|
|
26
26
|
],
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@quenty/baseobject": "^10.8.
|
|
29
|
-
"@quenty/loader": "^10.8.
|
|
30
|
-
"@quenty/lrucache": "^1.6.
|
|
31
|
-
"@quenty/promise": "^10.10.
|
|
32
|
-
"@quenty/queue": "^2.3.
|
|
33
|
-
"@quenty/rx": "^13.17.
|
|
34
|
-
"@quenty/tuple": "^1.5.
|
|
28
|
+
"@quenty/baseobject": "^10.8.3",
|
|
29
|
+
"@quenty/loader": "^10.8.3",
|
|
30
|
+
"@quenty/lrucache": "^1.6.3",
|
|
31
|
+
"@quenty/promise": "^10.10.4",
|
|
32
|
+
"@quenty/queue": "^2.3.3",
|
|
33
|
+
"@quenty/rx": "^13.17.3",
|
|
34
|
+
"@quenty/tuple": "^1.5.3"
|
|
35
35
|
},
|
|
36
36
|
"publishConfig": {
|
|
37
37
|
"access": "public"
|
|
38
38
|
},
|
|
39
|
-
"gitHead": "
|
|
39
|
+
"gitHead": "b06c070ae91d5dab7bd8de6e290ad2caabb15d8f"
|
|
40
40
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
--!strict
|
|
1
2
|
--[=[
|
|
2
3
|
Aggregates all requests into one big send request to deduplicate the request
|
|
3
4
|
|
|
@@ -15,6 +16,20 @@ local Aggregator = setmetatable({}, BaseObject)
|
|
|
15
16
|
Aggregator.ClassName = "Aggregator"
|
|
16
17
|
Aggregator.__index = Aggregator
|
|
17
18
|
|
|
19
|
+
export type PromiseBulkQuery<T> = ({ number }) -> Promise.Promise<T>
|
|
20
|
+
|
|
21
|
+
export type Aggregator<T> = typeof(setmetatable(
|
|
22
|
+
{} :: {
|
|
23
|
+
_debugName: string,
|
|
24
|
+
_promiseBatchQuery: ({ number }) -> Promise.Promise<T>,
|
|
25
|
+
_promisesLruCache: any,
|
|
26
|
+
_maxBatchSize: number,
|
|
27
|
+
_unsentCount: number,
|
|
28
|
+
_unsentPromises: { [number]: Promise.Promise<T> },
|
|
29
|
+
},
|
|
30
|
+
{} :: typeof({ __index = Aggregator })
|
|
31
|
+
)) & BaseObject.BaseObject
|
|
32
|
+
|
|
18
33
|
--[=[
|
|
19
34
|
Creates a new aggregator that aggregates promised results together
|
|
20
35
|
|
|
@@ -23,10 +38,10 @@ Aggregator.__index = Aggregator
|
|
|
23
38
|
|
|
24
39
|
@return Aggregator<T>
|
|
25
40
|
]=]
|
|
26
|
-
function Aggregator.new(debugName: string, promiseBulkQuery)
|
|
41
|
+
function Aggregator.new<T>(debugName: string, promiseBulkQuery: PromiseBulkQuery<T>): Aggregator<T>
|
|
27
42
|
assert(type(debugName) == "string", "Bad debugName")
|
|
28
43
|
|
|
29
|
-
local self = setmetatable(BaseObject.new(), Aggregator)
|
|
44
|
+
local self: Aggregator<T> = setmetatable(BaseObject.new() :: any, Aggregator)
|
|
30
45
|
|
|
31
46
|
self._debugName = debugName
|
|
32
47
|
self._promiseBatchQuery = assert(promiseBulkQuery, "No promiseBulkQuery")
|
|
@@ -44,7 +59,7 @@ end
|
|
|
44
59
|
Sets the max batch size
|
|
45
60
|
@param maxBatchSize number
|
|
46
61
|
]=]
|
|
47
|
-
function Aggregator
|
|
62
|
+
function Aggregator.SetMaxBatchSize<T>(self: Aggregator<T>, maxBatchSize: number)
|
|
48
63
|
assert(type(maxBatchSize) == "number", "Bad maxBatchSize")
|
|
49
64
|
assert(self._unsentCount == 0, "Cannot set while unsent values exist")
|
|
50
65
|
|
|
@@ -55,7 +70,7 @@ end
|
|
|
55
70
|
@param id number
|
|
56
71
|
@return Promise<T>
|
|
57
72
|
]=]
|
|
58
|
-
function Aggregator
|
|
73
|
+
function Aggregator.Promise<T>(self: Aggregator<T>, id: number)
|
|
59
74
|
assert(type(id) == "number", "Bad id")
|
|
60
75
|
|
|
61
76
|
local found = self._promisesLruCache:get(id)
|
|
@@ -80,13 +95,13 @@ end
|
|
|
80
95
|
@param id number
|
|
81
96
|
@return Observable<T>
|
|
82
97
|
]=]
|
|
83
|
-
function Aggregator
|
|
98
|
+
function Aggregator.Observe<T>(self: Aggregator<T>, id: number)
|
|
84
99
|
assert(type(id) == "number", "Bad id")
|
|
85
100
|
|
|
86
101
|
return Rx.fromPromise(self:Promise(id))
|
|
87
102
|
end
|
|
88
103
|
|
|
89
|
-
function Aggregator
|
|
104
|
+
function Aggregator._sendBatchedPromises<T>(self: Aggregator<T>, promiseMap)
|
|
90
105
|
assert(promiseMap, "No promiseMap")
|
|
91
106
|
|
|
92
107
|
local idList = {}
|
|
@@ -102,8 +117,7 @@ function Aggregator:_sendBatchedPromises(promiseMap)
|
|
|
102
117
|
|
|
103
118
|
assert(#idList <= self._maxBatchSize, "Too many idList sent")
|
|
104
119
|
|
|
105
|
-
self._maid:GivePromise(self._promiseBatchQuery(idList))
|
|
106
|
-
:Then(function(result)
|
|
120
|
+
self._maid:GivePromise(self._promiseBatchQuery(idList)):Then(function(result)
|
|
107
121
|
assert(type(result) == "table", "Bad result")
|
|
108
122
|
|
|
109
123
|
for _, data in result do
|
|
@@ -119,16 +133,16 @@ function Aggregator:_sendBatchedPromises(promiseMap)
|
|
|
119
133
|
for id, promise in unresolvedMap do
|
|
120
134
|
promise:Reject(string.format("[Aggregator] %s failed to get result for id %d", self._debugName, id))
|
|
121
135
|
end
|
|
122
|
-
|
|
136
|
+
end, function(err, ...)
|
|
123
137
|
local text = string.format("[Aggregator] %s failed to get bulk result - %q", self._debugName, tostring(err))
|
|
124
138
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
139
|
+
for _, item in unresolvedMap do
|
|
140
|
+
item:Reject(text, ...)
|
|
141
|
+
end
|
|
142
|
+
end)
|
|
129
143
|
end
|
|
130
144
|
|
|
131
|
-
function Aggregator
|
|
145
|
+
function Aggregator._resetQueue<T>(self: Aggregator<T>)
|
|
132
146
|
local promiseMap = self._unsentPromises
|
|
133
147
|
|
|
134
148
|
self._maid._queue = nil
|
|
@@ -138,7 +152,7 @@ function Aggregator:_resetQueue()
|
|
|
138
152
|
return promiseMap
|
|
139
153
|
end
|
|
140
154
|
|
|
141
|
-
function Aggregator
|
|
155
|
+
function Aggregator._queueBatchRequests<T>(self: Aggregator<T>)
|
|
142
156
|
if self._unsentCount >= self._maxBatchSize then
|
|
143
157
|
self:_sendBatchedPromises(self:_resetQueue())
|
|
144
158
|
return
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
--!strict
|
|
1
2
|
--[=[
|
|
2
3
|
@class RateAggregator
|
|
3
4
|
]=]
|
|
@@ -9,19 +10,40 @@ local Queue = require("Queue")
|
|
|
9
10
|
local Promise = require("Promise")
|
|
10
11
|
local TupleLookup = require("TupleLookup")
|
|
11
12
|
local LRUCache = require("LRUCache")
|
|
13
|
+
local _Tuple = require("Tuple")
|
|
12
14
|
|
|
13
15
|
local RateAggregator = setmetatable({}, BaseObject)
|
|
14
16
|
RateAggregator.ClassName = "RateAggregator"
|
|
15
17
|
RateAggregator.__index = RateAggregator
|
|
16
18
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
+
export type QueueEntry<TArgs..., T...> = {
|
|
20
|
+
promise: Promise.Promise<T...>,
|
|
21
|
+
tuple: _Tuple.Tuple<TArgs...>,
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export type RateAggregator<TArgs..., T...> = typeof(setmetatable(
|
|
25
|
+
{} :: {
|
|
26
|
+
_promiseQuery: (TArgs...) -> Promise.Promise<T...>,
|
|
27
|
+
_maxRequestsPerSecond: number,
|
|
28
|
+
_minWaitTime: number,
|
|
29
|
+
_bankedWaitTime: number,
|
|
30
|
+
_lastQueryTime: number,
|
|
31
|
+
_queueRunning: boolean,
|
|
32
|
+
_queue: Queue.Queue<QueueEntry<(TArgs...), (T...)>>,
|
|
33
|
+
_tupleLookup: TupleLookup.TupleLookup,
|
|
34
|
+
_promisesLruCache: any,
|
|
35
|
+
},
|
|
36
|
+
{} :: typeof({ __index = RateAggregator })
|
|
37
|
+
)) & BaseObject.BaseObject
|
|
38
|
+
|
|
39
|
+
function RateAggregator.new<TArgs..., T...>(promiseQuery: (TArgs...) -> Promise.Promise<T...>): RateAggregator<TArgs..., T...>
|
|
40
|
+
local self: RateAggregator<TArgs..., T...> = setmetatable(BaseObject.new() :: any, RateAggregator)
|
|
19
41
|
|
|
20
42
|
self._promiseQuery = promiseQuery
|
|
21
43
|
|
|
22
44
|
-- Configuration
|
|
23
45
|
self._maxRequestsPerSecond = 50
|
|
24
|
-
self._minWaitTime = 1/60
|
|
46
|
+
self._minWaitTime = 1 / 60
|
|
25
47
|
|
|
26
48
|
-- State tracking
|
|
27
49
|
self._bankedWaitTime = 0
|
|
@@ -35,7 +57,7 @@ function RateAggregator.new(promiseQuery)
|
|
|
35
57
|
return self
|
|
36
58
|
end
|
|
37
59
|
|
|
38
|
-
function RateAggregator
|
|
60
|
+
function RateAggregator.SetMaxRequestsPerSecond<TArgs..., T...>(self: RateAggregator<TArgs..., T...>, maxRequestPerSecond: number)
|
|
39
61
|
self._maxRequestsPerSecond = maxRequestPerSecond
|
|
40
62
|
end
|
|
41
63
|
|
|
@@ -45,7 +67,7 @@ end
|
|
|
45
67
|
@param ... any
|
|
46
68
|
@return Observable<T>
|
|
47
69
|
]=]
|
|
48
|
-
function RateAggregator
|
|
70
|
+
function RateAggregator.Promise<TArgs..., T...>(self: RateAggregator<TArgs..., T...>, ...: T...): Promise.Promise<T...>
|
|
49
71
|
local promise = self._maid:GivePromise(Promise.new())
|
|
50
72
|
|
|
51
73
|
local tuple = self._tupleLookup:ToTuple(...)
|
|
@@ -55,8 +77,8 @@ function RateAggregator:Promise(...)
|
|
|
55
77
|
end
|
|
56
78
|
|
|
57
79
|
self._queue:PushRight({
|
|
58
|
-
tuple = tuple
|
|
59
|
-
promise = promise
|
|
80
|
+
tuple = tuple,
|
|
81
|
+
promise = promise,
|
|
60
82
|
})
|
|
61
83
|
|
|
62
84
|
self._promisesLruCache:set(tuple, promise)
|
|
@@ -66,7 +88,7 @@ function RateAggregator:Promise(...)
|
|
|
66
88
|
return promise
|
|
67
89
|
end
|
|
68
90
|
|
|
69
|
-
function RateAggregator
|
|
91
|
+
function RateAggregator._startQueue<TArgs..., T...>(self: RateAggregator<TArgs..., T...>)
|
|
70
92
|
if self._queueRunning then
|
|
71
93
|
return
|
|
72
94
|
end
|