agentfootprint
Version:
The explainable agent framework — backtrack a wrong answer to the exact context that caused it (evidence, not guesses). Built on footprintjs.
49 lines • 1.69 kB
JavaScript
/**
* hosting/signin/checkGate — a door-wide cap on concurrent password checks.
*
* A password check is slow on purpose (scrypt holds 128 MiB and a thread for a
* sizeable fraction of a second; a directory bind is a network round trip). An
* unauthenticated burst of parallel logins would otherwise queue hundreds of
* them and starve the process's shared thread pool — file I/O, DNS, zlib — for
* everybody. So at most `concurrent` checks run at once, at most `queue` wait,
* and anything beyond is refused at once (503 with `Retry-After`).
*/
export function checkGate(options = {}) {
const concurrent = whole(options.concurrent ?? 4, 'concurrent', 1);
const queue = whole(options.queue ?? 32, 'queue', 0);
let running = 0;
const waiting = [];
const release = () => {
const next = waiting.shift();
if (next !== undefined)
next();
else
running -= 1;
};
return {
concurrent,
async run(check) {
if (running >= concurrent) {
if (waiting.length >= queue)
return undefined;
await new Promise((resolve) => waiting.push(resolve));
}
else {
running += 1;
}
try {
return { value: await check() };
}
finally {
release();
}
},
};
}
function whole(value, name, min) {
if (!Number.isInteger(value) || value < min) {
throw new TypeError(`[hosting] signInDoor checks.${name} is a whole number, ${min} or more.`);
}
return value;
}
//# sourceMappingURL=checkGate.js.map