Files
documenso/packages/lib/server-only/document-conversion/circuit-breaker.ts
T
Lucas Smith bc184d445f feat: support DOCX uploads via Gotenberg (#2801)
Uploaded .docx files are converted to PDF on the server using a
Gotenberg
sidecar before entering the normal envelope pipeline. The feature is
opt-in via NEXT_PRIVATE_DOCUMENT_CONVERSION_URL; when unset, only PDF
uploads are accepted.

A per-process circuit breaker opens for 30s after a conversion failure
to shed load.

Ships a dev Dockerfile that layers Microsoft Core Fonts and additional
language fonts
onto the upstream Gotenberg image for better fidelity.

Co-authored-by: Ephraim Duncan
<55143799+ephraimduncan@users.noreply.github.com>

Co-authored-by: Ephraim Duncan <55143799+ephraimduncan@users.noreply.github.com>
2026-05-13 15:06:21 +10:00

38 lines
1.2 KiB
TypeScript

/**
* In-process circuit breaker for the document conversion service.
*
* Behaviour: any failure opens the circuit for `COOLDOWN_MS`. While open,
* callers should fail fast without hitting the network. The first request
* after the cooldown is allowed through and either closes the circuit (on
* success) or re-opens it for another cooldown window (on failure).
*
* State is stored on `globalThis` so it survives Vite/Remix HMR in dev and
* is unambiguously process-wide. This module is intentionally pure and
* synchronous: no I/O, no logger import — callers handle observability.
*/
const COOLDOWN_MS = 30_000;
declare global {
// eslint-disable-next-line no-var
var __documensoConversionCircuitOpenedAt: number | null | undefined;
}
export const isCircuitOpen = (): boolean => {
const openedAt = globalThis.__documensoConversionCircuitOpenedAt;
if (!openedAt) {
return false;
}
return Date.now() - openedAt < COOLDOWN_MS;
};
export const recordSuccess = (): void => {
globalThis.__documensoConversionCircuitOpenedAt = null;
};
export const recordFailure = (): void => {
globalThis.__documensoConversionCircuitOpenedAt = Date.now();
};