Comparing version 25.0.0 to 26.0.0
@@ -6,2 +6,3 @@ import { juxt, pairRight, stack } from "./juxt.js"; | ||
import { pipe } from "./composition.js"; | ||
import { sleep } from "./time.js"; | ||
const executeTasks = (execute) => pipe( | ||
@@ -67,1 +68,14 @@ // @ts-expect-error reason: pipe can't figure out the typing here. | ||
}); | ||
export const retry = (waitMs, times, f) => | ||
// @ts-expect-error cannot infer | ||
times | ||
? async (...x) => { | ||
try { | ||
return await f(...x); | ||
} | ||
catch (e) { | ||
console.error(`failed. retries left: ${times}`, e); | ||
return sleep(waitMs).then(() => retry(waitMs, times - 1, f)(...x)); | ||
} | ||
} | ||
: f; |
@@ -14,3 +14,3 @@ import { sleep } from "./time.js"; | ||
}); | ||
export const retry = async (f) => { | ||
export const keepTryingEvery50ms = async (f) => { | ||
while (!(await f())) { | ||
@@ -20,3 +20,3 @@ await sleep(50); | ||
}; | ||
export const makeLockWithId = (set) => (id) => retry(() => set(id)); | ||
export const makeLockWithId = (set) => (id) => keepTryingEvery50ms(() => set(id)); | ||
export const withLockByInput = (argsToLockId, lock, unlock, f) => (...args) => { | ||
@@ -50,3 +50,3 @@ const lockId = argsToLockId(...args); | ||
let lockObj = 0; | ||
return withLock((...task) => retry(() => { | ||
return withLock((...task) => keepTryingEvery50ms(() => { | ||
if (lockObj < maxParallelism) { | ||
@@ -64,3 +64,3 @@ lockObj += weight(...task); | ||
let history = []; | ||
return withLock((...task) => retry(() => { | ||
return withLock((...task) => keepTryingEvery50ms(() => { | ||
history = history.filter(({ timestamp }) => timestamp > Date.now() - timeWindowMs); | ||
@@ -67,0 +67,0 @@ const currentWeight = weight(...task); |
@@ -6,3 +6,3 @@ { | ||
"name": "gamla", | ||
"version": "25.0.0", | ||
"version": "26.0.0", | ||
"description": "Functional programming with async and type safety", | ||
@@ -9,0 +9,0 @@ "license": "MIT", |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.timeout = exports.batch = void 0; | ||
exports.retry = exports.timeout = exports.batch = void 0; | ||
const juxt_js_1 = require("./juxt.js"); | ||
@@ -9,2 +9,3 @@ const operator_js_1 = require("./operator.js"); | ||
const composition_js_1 = require("./composition.js"); | ||
const time_js_1 = require("./time.js"); | ||
const executeTasks = (execute) => (0, composition_js_1.pipe)( | ||
@@ -72,1 +73,15 @@ // @ts-expect-error reason: pipe can't figure out the typing here. | ||
exports.timeout = timeout; | ||
const retry = (waitMs, times, f) => | ||
// @ts-expect-error cannot infer | ||
times | ||
? async (...x) => { | ||
try { | ||
return await f(...x); | ||
} | ||
catch (e) { | ||
console.error(`failed. retries left: ${times}`, e); | ||
return (0, time_js_1.sleep)(waitMs).then(() => (0, exports.retry)(waitMs, times - 1, f)(...x)); | ||
} | ||
} | ||
: f; | ||
exports.retry = retry; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.rateLimit = exports.throttle = exports.sequentialized = exports.withLockByInput = exports.makeLockWithId = exports.retry = exports.withLock = void 0; | ||
exports.rateLimit = exports.throttle = exports.sequentialized = exports.withLockByInput = exports.makeLockWithId = exports.keepTryingEvery50ms = exports.withLock = void 0; | ||
const time_js_1 = require("./time.js"); | ||
@@ -18,3 +18,3 @@ const withLock = (lock, unlock, f) => (async (...args) => { | ||
exports.withLock = withLock; | ||
const retry = async (f) => { | ||
const keepTryingEvery50ms = async (f) => { | ||
while (!(await f())) { | ||
@@ -24,4 +24,4 @@ await (0, time_js_1.sleep)(50); | ||
}; | ||
exports.retry = retry; | ||
const makeLockWithId = (set) => (id) => (0, exports.retry)(() => set(id)); | ||
exports.keepTryingEvery50ms = keepTryingEvery50ms; | ||
const makeLockWithId = (set) => (id) => (0, exports.keepTryingEvery50ms)(() => set(id)); | ||
exports.makeLockWithId = makeLockWithId; | ||
@@ -58,3 +58,3 @@ const withLockByInput = (argsToLockId, lock, unlock, f) => (...args) => { | ||
let lockObj = 0; | ||
return (0, exports.withLock)((...task) => (0, exports.retry)(() => { | ||
return (0, exports.withLock)((...task) => (0, exports.keepTryingEvery50ms)(() => { | ||
if (lockObj < maxParallelism) { | ||
@@ -73,3 +73,3 @@ lockObj += weight(...task); | ||
let history = []; | ||
return (0, exports.withLock)((...task) => (0, exports.retry)(() => { | ||
return (0, exports.withLock)((...task) => (0, exports.keepTryingEvery50ms)(() => { | ||
history = history.filter(({ timestamp }) => timestamp > Date.now() - timeWindowMs); | ||
@@ -76,0 +76,0 @@ const currentWeight = weight(...task); |
@@ -1,2 +0,2 @@ | ||
import { ElementOf } from "./typing.js"; | ||
import { AsyncFunction, ElementOf } from "./typing.js"; | ||
type Executor<TaskInput, Output> = (_: TaskInput[]) => Promise<Output>; | ||
@@ -9,2 +9,3 @@ /** | ||
export declare const timeout: <Args extends unknown[], Output>(ms: number, fallback: (..._: Args) => Output | Promise<Output>, f: (..._: Args) => Promise<Output>) => (...args: Args) => Promise<Output>; | ||
export declare const retry: <F extends AsyncFunction>(waitMs: number, times: number, f: F) => F; | ||
export {}; |
import { AsyncFunction } from "./typing.js"; | ||
export declare const withLock: <Function_1 extends AsyncFunction>(lock: (...task: Parameters<Function_1>) => void | Promise<void>, unlock: (...task: Parameters<Function_1>) => void | Promise<void>, f: Function_1) => Function_1; | ||
export declare const retry: (f: () => boolean | Promise<boolean>) => Promise<void>; | ||
export declare const keepTryingEvery50ms: (f: () => boolean | Promise<boolean>) => Promise<void>; | ||
export declare const makeLockWithId: <Key>(set: (_: Key) => boolean | Promise<boolean>) => (id: Key) => Promise<void>; | ||
@@ -5,0 +5,0 @@ export declare const withLockByInput: <Function_1 extends AsyncFunction>(argsToLockId: (..._: Parameters<Function_1>) => string, lock: (_: string) => Promise<void>, unlock: (_: string) => Promise<void>, f: Function_1) => (...args: Parameters<Function_1>) => Promise<any>; |
191458
1679