@nxtedition/scheduler 3.1.1 → 3.1.2
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/lib/throttle.d.ts +1 -1
- package/lib/throttle.d.ts.map +1 -1
- package/lib/throttle.js +43 -33
- package/lib/throttle.js.map +1 -1
- package/package.json +2 -2
package/lib/throttle.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ export declare class Throttle extends Queue {
|
|
|
6
6
|
bytesPerSecond?: number;
|
|
7
7
|
});
|
|
8
8
|
static makeSharedState(bytesPerSecond: number): SharedArrayBuffer;
|
|
9
|
+
[Symbol.dispose](): void;
|
|
9
10
|
stream(priority?: Priority): Transform;
|
|
10
11
|
acquire(fn: () => unknown, bytes: number, priority?: Priority): boolean;
|
|
11
12
|
get stats(): {
|
|
@@ -15,6 +16,5 @@ export declare class Throttle extends Queue {
|
|
|
15
16
|
count: number;
|
|
16
17
|
}[];
|
|
17
18
|
};
|
|
18
|
-
refill(): void;
|
|
19
19
|
}
|
|
20
20
|
//# sourceMappingURL=throttle.d.ts.map
|
package/lib/throttle.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"throttle.d.ts","sourceRoot":"","sources":["../src/throttle.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AACvC,OAAO,EAA4B,KAAK,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"throttle.d.ts","sourceRoot":"","sources":["../src/throttle.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AACvC,OAAO,EAA4B,KAAK,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,CAAA;AAK3E,qBAAa,QAAS,SAAQ,KAAK;;gBAOrB,IAAI,EAAE,iBAAiB,GAAG;QAAE,cAAc,CAAC,EAAE,MAAM,CAAA;KAAE;IAMjE,MAAM,CAAC,eAAe,CAAC,cAAc,EAAE,MAAM;IAI7C,CAAC,MAAM,CAAC,OAAO,CAAC;IAShB,MAAM,CAAC,QAAQ,GAAE,QAAuB;IAQxC,OAAO,CAAC,EAAE,EAAE,MAAM,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,GAAE,QAAuB,GAAG,OAAO;IA+BrF,IAAI,KAAK;;;;;;MAMR;CAwEF"}
|
package/lib/throttle.js
CHANGED
|
@@ -1,32 +1,50 @@
|
|
|
1
1
|
import { Transform } from 'node:stream';
|
|
2
2
|
import { FastQueue, parsePriority, Queue } from "./queue.js";
|
|
3
|
+
import { isMainThread } from 'node:worker_threads';
|
|
3
4
|
const TOKENS_INDEX = 2;
|
|
4
5
|
export class Throttle extends Queue {
|
|
5
6
|
#singleThreadTokens = 0;
|
|
6
7
|
// Set last refill time to -Infinity so first refill() always fills a full bucket.
|
|
7
8
|
#lastRefillTime = -Infinity;
|
|
8
|
-
#
|
|
9
|
+
#refillTimer = null;
|
|
10
|
+
#drainTimer = null;
|
|
9
11
|
constructor(opts) {
|
|
10
12
|
super(opts instanceof SharedArrayBuffer ? opts : { concurrency: opts?.bytesPerSecond });
|
|
13
|
+
this.#refillTimer = !this.stateView || isMainThread ? setInterval(() => this.#refill(), 100).unref() : null;
|
|
14
|
+
this.#drainTimer = this.stateView && !isMainThread ? setInterval(() => this.#drain(), 100).unref() : null;
|
|
11
15
|
}
|
|
12
16
|
static makeSharedState(bytesPerSecond) {
|
|
13
17
|
return super.makeSharedState(bytesPerSecond);
|
|
14
18
|
}
|
|
19
|
+
[Symbol.dispose]() {
|
|
20
|
+
if (this.#refillTimer) {
|
|
21
|
+
clearInterval(this.#refillTimer);
|
|
22
|
+
}
|
|
23
|
+
if (this.#drainTimer) {
|
|
24
|
+
clearInterval(this.#drainTimer);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
15
27
|
stream(priority = Queue.NORMAL) {
|
|
16
28
|
return new Transform({
|
|
17
29
|
transform: (chunk, _encoding, callback) => {
|
|
18
|
-
this.acquire(() =>
|
|
19
|
-
callback(null, chunk);
|
|
20
|
-
}, chunk.length, priority);
|
|
30
|
+
this.acquire(() => callback(null, chunk), chunk.length, priority);
|
|
21
31
|
},
|
|
22
32
|
});
|
|
23
33
|
}
|
|
24
34
|
acquire(fn, bytes, priority = Queue.NORMAL) {
|
|
35
|
+
if ((!this.stateView || isMainThread) && this.#tokens < bytes) {
|
|
36
|
+
this.#refill();
|
|
37
|
+
}
|
|
25
38
|
// There is a possiblity that this check passes for two threads, but should only have passed for one of them.
|
|
26
39
|
// Given that the concurrency limit is a soft limit, this is not a problem and will just mean that we might briefly exceed the concurrency limit until the next refill.
|
|
27
40
|
if (this.pending === 0 && this.#tokens >= bytes) {
|
|
28
41
|
// Nothing in the queue, and enough tokens to run immediately.
|
|
29
|
-
this
|
|
42
|
+
if (this.stateView) {
|
|
43
|
+
Atomics.sub(this.stateView, TOKENS_INDEX, bytes);
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
this.#singleThreadTokens -= bytes;
|
|
47
|
+
}
|
|
30
48
|
fn();
|
|
31
49
|
return true;
|
|
32
50
|
}
|
|
@@ -36,10 +54,6 @@ export class Throttle extends Queue {
|
|
|
36
54
|
this.deferred += 1;
|
|
37
55
|
queue.arr.push(fn, bytes);
|
|
38
56
|
queue.cnt += 1;
|
|
39
|
-
if (!this.#draining) {
|
|
40
|
-
this.#draining = true;
|
|
41
|
-
setImmediate(this.#drain);
|
|
42
|
-
}
|
|
43
57
|
return false;
|
|
44
58
|
}
|
|
45
59
|
get stats() {
|
|
@@ -52,15 +66,7 @@ export class Throttle extends Queue {
|
|
|
52
66
|
get #tokens() {
|
|
53
67
|
return this.stateView ? this.stateView[TOKENS_INDEX] : this.#singleThreadTokens;
|
|
54
68
|
}
|
|
55
|
-
|
|
56
|
-
if (this.stateView) {
|
|
57
|
-
Atomics.store(this.stateView, TOKENS_INDEX, value);
|
|
58
|
-
}
|
|
59
|
-
else {
|
|
60
|
-
this.#singleThreadTokens = value;
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
refill() {
|
|
69
|
+
#refill() {
|
|
64
70
|
const currentToken = this.#tokens;
|
|
65
71
|
if (currentToken >= this.concurrency) {
|
|
66
72
|
// We are already at or above capacity, so just update the last refill time and return.
|
|
@@ -69,14 +75,19 @@ export class Throttle extends Queue {
|
|
|
69
75
|
}
|
|
70
76
|
const now = performance.now();
|
|
71
77
|
const elapsed = (now - this.#lastRefillTime) / 1000;
|
|
72
|
-
|
|
78
|
+
const newTokens = Math.min(this.concurrency - currentToken, elapsed * this.concurrency);
|
|
79
|
+
if (this.stateView) {
|
|
80
|
+
Atomics.add(this.stateView, TOKENS_INDEX, newTokens | 0);
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
this.#singleThreadTokens += newTokens;
|
|
84
|
+
}
|
|
73
85
|
this.#lastRefillTime = now;
|
|
74
|
-
if (!this
|
|
75
|
-
this.#
|
|
76
|
-
setImmediate(this.#drain);
|
|
86
|
+
if (!this.stateView || isMainThread) {
|
|
87
|
+
this.#drain();
|
|
77
88
|
}
|
|
78
89
|
}
|
|
79
|
-
#drain
|
|
90
|
+
#drain() {
|
|
80
91
|
while (this.pending > 0) {
|
|
81
92
|
const queue = this.getNextQueue();
|
|
82
93
|
if (queue == null || queue.cnt === 0) {
|
|
@@ -85,19 +96,19 @@ export class Throttle extends Queue {
|
|
|
85
96
|
const bytes = queue.arr[queue.idx + 1];
|
|
86
97
|
const currentTokens = this.#tokens;
|
|
87
98
|
if (currentTokens < bytes) {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
// so we need to poll since there's no cross-thread signaling.
|
|
91
|
-
setTimeout(this.#drain, 10);
|
|
92
|
-
return;
|
|
93
|
-
}
|
|
94
|
-
break;
|
|
99
|
+
this.#drainTimer?.refresh();
|
|
100
|
+
return;
|
|
95
101
|
}
|
|
96
102
|
const fn = queue.arr[queue.idx];
|
|
97
103
|
queue.arr[queue.idx++] = null;
|
|
98
104
|
queue.arr[queue.idx++] = null;
|
|
99
105
|
queue.cnt -= 1;
|
|
100
|
-
this
|
|
106
|
+
if (this.stateView) {
|
|
107
|
+
Atomics.sub(this.stateView, TOKENS_INDEX, bytes);
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
this.#singleThreadTokens -= bytes;
|
|
111
|
+
}
|
|
101
112
|
this.pending -= 1;
|
|
102
113
|
if (queue.cnt === 0) {
|
|
103
114
|
queue.idx = 0;
|
|
@@ -109,7 +120,6 @@ export class Throttle extends Queue {
|
|
|
109
120
|
}
|
|
110
121
|
fn();
|
|
111
122
|
}
|
|
112
|
-
|
|
113
|
-
};
|
|
123
|
+
}
|
|
114
124
|
}
|
|
115
125
|
//# sourceMappingURL=throttle.js.map
|
package/lib/throttle.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"throttle.js","sourceRoot":"","sources":["../src/throttle.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AACvC,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,KAAK,EAAiB,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"throttle.js","sourceRoot":"","sources":["../src/throttle.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nxtedition/scheduler",
|
|
3
|
-
"version": "3.1.
|
|
3
|
+
"version": "3.1.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
@@ -31,5 +31,5 @@
|
|
|
31
31
|
"rimraf": "^6.1.3",
|
|
32
32
|
"typescript": "^5.9.3"
|
|
33
33
|
},
|
|
34
|
-
"gitHead": "
|
|
34
|
+
"gitHead": "15cf2221f806675de2c224219a7f11ffc17ffeb3"
|
|
35
35
|
}
|