Files
suaveplan/packages/api-stack/api/api-ws/src/backpressure/backpressure.ts
2026-05-27 23:29:53 +01:00

51 lines
1.6 KiB
TypeScript

import { WS_CODES, WsError } from "../error-codes/error-codes.js";
/**
* Policy describing how engines bound their per-connection outbound queue.
*
* `maxQueuedMessages` is the upper bound; once a connection has more
* messages queued than this, the engine MUST close it with the
* `BACKPRESSURE_EVICTED` reason and remove it from the registry. The
* default of 256 matches design doc §11.4.
*/
export interface BackpressurePolicy {
readonly maxQueuedMessages: number;
}
/** Default policy applied when no override is supplied. */
export const DEFAULT_BACKPRESSURE_POLICY: BackpressurePolicy = Object.freeze({
maxQueuedMessages: 256,
});
/**
* Reusable evaluator for engines. Given the current queue depth and a
* policy, returns the action the engine MUST take.
*
* The contract package owns this helper so every concrete engine
* (`api-ws-bun`, future browser shims) shares one definition of the
* eviction trigger.
*/
export type BackpressureAction = "accept" | "evict";
export function evaluateBackpressure(
queuedMessages: number,
policy: BackpressurePolicy = DEFAULT_BACKPRESSURE_POLICY
): BackpressureAction {
if (queuedMessages > policy.maxQueuedMessages) {
return "evict";
}
return "accept";
}
/**
* Helper that engines call when the policy has been violated. Throws a
* `WsError` so the engine has one clean place to convert backpressure into
* the documented close-frame reason.
*/
export function raiseBackpressureEvicted(connectionId: string): never {
throw new WsError(
WS_CODES.BACKPRESSURE_EVICTED,
`connection ${connectionId} evicted: send queue overflow`
);
}