socket-function 1.1.23 → 1.1.25
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 +12 -1
- package/package.json +1 -1
- package/src/batching.d.ts +12 -1
- package/src/batching.ts +74 -1
package/index.d.ts
CHANGED
|
@@ -609,13 +609,24 @@ 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. ONLY applies if your function does not return promises. Default = 1000ms */
|
|
624
|
+
maxBlockingTime?: number;
|
|
625
|
+
/** Fraction of time spent active vs yielded. e.g. 0.5 => after running X ms, wait X ms before continuing. */
|
|
626
|
+
maxActiveFraction?: number;
|
|
627
|
+
doNotWarnOnSlow?: boolean;
|
|
628
|
+
name?: string;
|
|
629
|
+
}): Promise<R[]>;
|
|
619
630
|
|
|
620
631
|
}
|
|
621
632
|
|
package/package.json
CHANGED
package/src/batching.d.ts
CHANGED
|
@@ -33,10 +33,21 @@ 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. ONLY applies if your function does not return promises. Default = 1000ms */
|
|
48
|
+
maxBlockingTime?: number;
|
|
49
|
+
/** Fraction of time spent active vs yielded. e.g. 0.5 => after running X ms, wait X ms before continuing. */
|
|
50
|
+
maxActiveFraction?: number;
|
|
51
|
+
doNotWarnOnSlow?: boolean;
|
|
52
|
+
name?: string;
|
|
53
|
+
}): 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,75 @@ 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. ONLY applies if your function does not return promises. Default = 1000ms */
|
|
379
|
+
maxBlockingTime?: number;
|
|
380
|
+
/** Fraction of time spent active vs yielded. e.g. 0.5 => after running X ms, wait X ms before continuing. */
|
|
381
|
+
maxActiveFraction?: number;
|
|
382
|
+
doNotWarnOnSlow?: boolean;
|
|
383
|
+
name?: string;
|
|
384
|
+
}): Promise<R[]> {
|
|
385
|
+
let { data, fnc, maxActiveFraction, doNotWarnOnSlow, name } = config;
|
|
386
|
+
let maxBlockingTime = config.maxBlockingTime ?? 1000;
|
|
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 activeTimeSinceYield = 0;
|
|
411
|
+
try {
|
|
412
|
+
for (index = 0; index < data.length; index++) {
|
|
413
|
+
indexStartTime = Date.now();
|
|
414
|
+
let result = fnc(data[index]);
|
|
415
|
+
let isPromise = false;
|
|
416
|
+
if (result && typeof result === "object" && "then" in result) {
|
|
417
|
+
isPromise = true;
|
|
418
|
+
result = await result;
|
|
419
|
+
}
|
|
420
|
+
results.push(result);
|
|
421
|
+
|
|
422
|
+
activeTimeSinceYield += Date.now() - indexStartTime;
|
|
423
|
+
|
|
424
|
+
let backOffTime: number | undefined;
|
|
425
|
+
|
|
426
|
+
if (!isPromise && activeTimeSinceYield > maxBlockingTime) {
|
|
427
|
+
backOffTime = 0;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
if (maxActiveFraction !== undefined && maxActiveFraction > 0 && maxActiveFraction < 1) {
|
|
431
|
+
let target = activeTimeSinceYield / maxActiveFraction - activeTimeSinceYield;
|
|
432
|
+
backOffTime = Math.max(backOffTime ?? 0, target);
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
if (backOffTime !== undefined) {
|
|
436
|
+
await delay(backOffTime);
|
|
437
|
+
activeTimeSinceYield = 0;
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
} finally {
|
|
441
|
+
done = true;
|
|
442
|
+
}
|
|
443
|
+
return results;
|
|
371
444
|
}
|