socket-function 1.1.22 → 1.1.24
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/index.d.ts +13 -1
- package/package.json +1 -1
- package/src/batching.d.ts +13 -1
- package/src/batching.ts +66 -1
- package/src/promiseRace.ts +3 -3
package/index.d.ts
CHANGED
|
@@ -609,13 +609,25 @@ declare module "socket-function/src/batching" {
|
|
|
609
609
|
minDelay?: number;
|
|
610
610
|
maxDelay?: number;
|
|
611
611
|
}): T;
|
|
612
|
-
|
|
612
|
+
/** @deprecated Use safeLoop instead */
|
|
613
613
|
export declare const throttledLoop: typeof unblockLoop;
|
|
614
|
+
/** @deprecated Use safeLoop instead */
|
|
614
615
|
export declare function unblockLoop<T, R>(config: {
|
|
615
616
|
data: T[];
|
|
616
617
|
maxBlockingTime?: number;
|
|
617
618
|
backOffTime?: number;
|
|
618
619
|
} | T[], fnc: (item: T) => MaybePromise<R>): Promise<R[]>;
|
|
620
|
+
export declare function safeLoop<T, R>(config: {
|
|
621
|
+
data: T[];
|
|
622
|
+
fnc: (item: T) => MaybePromise<R>;
|
|
623
|
+
/** If set, yields after blocking for this many ms. */
|
|
624
|
+
maxBlockingTime?: number;
|
|
625
|
+
/** If set (with maxBlockingTime), the fraction of time spent active vs yielded.
|
|
626
|
+
* e.g. 0.5 => after blocking X ms, wait X ms before continuing. */
|
|
627
|
+
maxActiveFraction?: number;
|
|
628
|
+
doNotWarnOnSlow?: boolean;
|
|
629
|
+
name?: string;
|
|
630
|
+
}): Promise<R[]>;
|
|
619
631
|
|
|
620
632
|
}
|
|
621
633
|
|
package/package.json
CHANGED
package/src/batching.d.ts
CHANGED
|
@@ -33,10 +33,22 @@ export declare function retryFunctional<T extends AnyFunction>(fnc: T, config?:
|
|
|
33
33
|
minDelay?: number;
|
|
34
34
|
maxDelay?: number;
|
|
35
35
|
}): T;
|
|
36
|
-
|
|
36
|
+
/** @deprecated Use safeLoop instead */
|
|
37
37
|
export declare const throttledLoop: typeof unblockLoop;
|
|
38
|
+
/** @deprecated Use safeLoop instead */
|
|
38
39
|
export declare function unblockLoop<T, R>(config: {
|
|
39
40
|
data: T[];
|
|
40
41
|
maxBlockingTime?: number;
|
|
41
42
|
backOffTime?: number;
|
|
42
43
|
} | T[], fnc: (item: T) => MaybePromise<R>): Promise<R[]>;
|
|
44
|
+
export declare function safeLoop<T, R>(config: {
|
|
45
|
+
data: T[];
|
|
46
|
+
fnc: (item: T) => MaybePromise<R>;
|
|
47
|
+
/** If set, yields after blocking for this many ms. */
|
|
48
|
+
maxBlockingTime?: number;
|
|
49
|
+
/** If set (with maxBlockingTime), the fraction of time spent active vs yielded.
|
|
50
|
+
* e.g. 0.5 => after blocking X ms, wait X ms before continuing. */
|
|
51
|
+
maxActiveFraction?: number;
|
|
52
|
+
doNotWarnOnSlow?: boolean;
|
|
53
|
+
name?: string;
|
|
54
|
+
}): Promise<R[]>;
|
package/src/batching.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { formatTime } from "./formatting/format";
|
|
1
2
|
import { PromiseObj, isNode, timeoutToError } from "./misc";
|
|
2
3
|
import { measureWrap } from "./profiling/measure";
|
|
3
4
|
import { AnyFunction, Args, MaybePromise } from "./types";
|
|
@@ -333,8 +334,9 @@ export function retryFunctional<T extends AnyFunction>(fnc: T, config?: {
|
|
|
333
334
|
} as any;
|
|
334
335
|
}
|
|
335
336
|
|
|
336
|
-
|
|
337
|
+
/** @deprecated Use safeLoop instead */
|
|
337
338
|
export const throttledLoop = unblockLoop;
|
|
339
|
+
/** @deprecated Use safeLoop instead */
|
|
338
340
|
export async function unblockLoop<T, R>(config: {
|
|
339
341
|
data: T[];
|
|
340
342
|
maxBlockingTime?: number;
|
|
@@ -368,4 +370,67 @@ export async function unblockLoop<T, R>(config: {
|
|
|
368
370
|
}
|
|
369
371
|
}
|
|
370
372
|
return results;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
export async function safeLoop<T, R>(config: {
|
|
376
|
+
data: T[];
|
|
377
|
+
fnc: (item: T) => MaybePromise<R>;
|
|
378
|
+
/** If set, yields after blocking for this many ms. */
|
|
379
|
+
maxBlockingTime?: number;
|
|
380
|
+
/** If set (with maxBlockingTime), the fraction of time spent active vs yielded.
|
|
381
|
+
* e.g. 0.5 => after blocking X ms, wait X ms before continuing. */
|
|
382
|
+
maxActiveFraction?: number;
|
|
383
|
+
doNotWarnOnSlow?: boolean;
|
|
384
|
+
name?: string;
|
|
385
|
+
}): Promise<R[]> {
|
|
386
|
+
let { data, fnc, maxBlockingTime, maxActiveFraction, doNotWarnOnSlow, name } = config;
|
|
387
|
+
|
|
388
|
+
let label = name || fnc.name || fnc.toString().slice(0, 100);
|
|
389
|
+
let startTime = Date.now();
|
|
390
|
+
let index = 0;
|
|
391
|
+
let indexStartTime = Date.now();
|
|
392
|
+
let done = false;
|
|
393
|
+
|
|
394
|
+
if (!doNotWarnOnSlow) {
|
|
395
|
+
void (async () => {
|
|
396
|
+
while (!done) {
|
|
397
|
+
await delay(5000);
|
|
398
|
+
if (done) break;
|
|
399
|
+
let message = `${label} @ ${index} / ${data.length} | ${formatTime(Date.now() - startTime)}`;
|
|
400
|
+
let timeOnCurrent = Date.now() - indexStartTime;
|
|
401
|
+
if (timeOnCurrent > 5000) {
|
|
402
|
+
message += `| SLOW INDEX (${index}) ${formatTime(timeOnCurrent)}+`;
|
|
403
|
+
}
|
|
404
|
+
console.log(message);
|
|
405
|
+
}
|
|
406
|
+
})();
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
let results: R[] = [];
|
|
410
|
+
let lastYieldTime = Date.now();
|
|
411
|
+
try {
|
|
412
|
+
for (index = 0; index < data.length; index++) {
|
|
413
|
+
indexStartTime = Date.now();
|
|
414
|
+
let result = fnc(data[index]);
|
|
415
|
+
if (result && typeof result === "object" && "then" in result) {
|
|
416
|
+
result = await result;
|
|
417
|
+
}
|
|
418
|
+
results.push(result);
|
|
419
|
+
|
|
420
|
+
if (maxBlockingTime !== undefined) {
|
|
421
|
+
let blockedFor = Date.now() - lastYieldTime;
|
|
422
|
+
if (blockedFor > maxBlockingTime) {
|
|
423
|
+
let backOffTime = 0;
|
|
424
|
+
if (maxActiveFraction !== undefined && maxActiveFraction > 0 && maxActiveFraction < 1) {
|
|
425
|
+
backOffTime = blockedFor / maxActiveFraction - blockedFor;
|
|
426
|
+
}
|
|
427
|
+
await delay(backOffTime);
|
|
428
|
+
lastYieldTime = Date.now();
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
} finally {
|
|
433
|
+
done = true;
|
|
434
|
+
}
|
|
435
|
+
return results;
|
|
371
436
|
}
|
package/src/promiseRace.ts
CHANGED
|
@@ -59,18 +59,18 @@ function connectPromiseToCallbackObj(promise: any, callbackObj: any) {
|
|
|
59
59
|
// We need to delete the callback lists once on finally happens. Because we only connect to the promise once, And so it'll only trigger us once. So removing it is the only way to get it to trigger us again if someone subscribes to a finished promise.
|
|
60
60
|
promiseCallbacks.delete(promise);
|
|
61
61
|
for (let fnc of callbackObj.onResolve.slice()) {
|
|
62
|
-
try { fnc(value); }
|
|
62
|
+
try { fnc(value); } catch { }
|
|
63
63
|
}
|
|
64
64
|
},
|
|
65
65
|
(value: any) => {
|
|
66
66
|
promiseCallbacks.delete(promise);
|
|
67
67
|
for (let fnc of callbackObj.onReject.slice()) {
|
|
68
|
-
try { fnc(value); }
|
|
68
|
+
try { fnc(value); } catch { }
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
71
|
).finally(() => {
|
|
72
72
|
for (let fnc of callbackObj.onFinally.slice()) {
|
|
73
|
-
try { fnc(); }
|
|
73
|
+
try { fnc(); } catch { }
|
|
74
74
|
}
|
|
75
75
|
});
|
|
76
76
|
}
|