@juspay/neurolink
Version:
The pipe layer of an AI nervous system: one interface connecting provider neurons to your application, across three inference types — generate, stream and decide. `decide` returns typed, calibrated judgements from a non-generative model (~400ms, ~$0.00002
195 lines (194 loc) • 8.08 kB
JavaScript
/**
* Parse serving identity conservatively from `/status`. A rolling status is
* trusted only when the worker-local fields agree with the supervisor snapshot.
*/
export function parseProxyServingWorkerIdentity(payload, rollingSupervisor) {
if (!payload || typeof payload !== "object") {
return null;
}
const value = payload;
if (typeof value.version !== "string" ||
!/^\d+\.\d+\.\d+$/.test(value.version) ||
!Number.isSafeInteger(value.pid) ||
Number(value.pid) <= 0) {
return null;
}
if (!rollingSupervisor) {
return { version: value.version, pid: Number(value.pid), generation: null };
}
const active = value.autoUpdate?.rolling?.active;
if (!active ||
active.version !== value.version ||
active.pid !== value.pid ||
!Number.isSafeInteger(active.generation) ||
Number(active.generation) <= 0) {
return null;
}
return {
version: value.version,
pid: Number(value.pid),
generation: Number(active.generation),
};
}
/** A long-running update may mutate live selection only for its original worker. */
export function isSameProxyServingWorker(expected, current) {
return (current?.version === expected.version &&
current.pid === expected.pid &&
current.generation === expected.generation);
}
/**
* A replacement updater starts from the newly installed package. The registry
* then reports no newer version even when its launchd parent still runs the
* old package, so parent reconciliation must be decided from both live
* generations instead of `updateAvailable` alone.
*/
export function shouldRefreshStaleSupervisor(options) {
return (!options.updateAvailable &&
options.rollingSupervisor &&
options.workerVersion === options.runningVersion &&
typeof options.supervisorVersion === "string" &&
options.supervisorVersion !== options.runningVersion);
}
/** An idle active worker alone does not make its supervisor safe to stop. */
export function isProxyRuntimeSettled(activity) {
return (activity.activeRequests === 0 &&
(activity.drainingWorkers ?? 0) === 0 &&
(activity.queuedSockets ?? 0) === 0 &&
(activity.pendingTransfers ?? 0) === 0 &&
(activity.candidateWorkers ?? 0) === 0);
}
/** Parse untrusted status conservatively; incomplete rolling evidence is busy. */
export function parseProxyRuntimeActivity(payload) {
if (!payload || typeof payload !== "object") {
return null;
}
const value = payload;
const active = value.activity?.activeRequests;
if (typeof active !== "number" ||
!Number.isSafeInteger(active) ||
active < 0) {
return null;
}
const result = {
activeRequests: active,
lastActivityAt: typeof value.activity?.lastActivityAt === "string"
? value.activity.lastActivityAt
: null,
};
const rolling = value.autoUpdate?.rolling;
if (value.autoUpdate?.supervisorPid && !rolling) {
return null;
}
if (rolling) {
if (!Array.isArray(rolling.draining) ||
typeof rolling.queuedSockets !== "number" ||
!Number.isSafeInteger(rolling.queuedSockets) ||
rolling.queuedSockets < 0 ||
typeof rolling.pendingTransfers !== "number" ||
!Number.isSafeInteger(rolling.pendingTransfers) ||
rolling.pendingTransfers < 0 ||
rolling.candidate === undefined) {
return null;
}
result.drainingWorkers = rolling.draining.length;
result.queuedSockets = rolling.queuedSockets;
result.pendingTransfers = rolling.pendingTransfers;
result.candidateWorkers = rolling.candidate === null ? 0 : 1;
}
return result;
}
function isQuiet(activity, quietThresholdMs, nowMs) {
if (!isProxyRuntimeSettled(activity)) {
return false;
}
if (!activity.lastActivityAt) {
return true;
}
const lastActivityMs = Date.parse(activity.lastActivityAt);
return (Number.isFinite(lastActivityMs) &&
nowMs - lastActivityMs >= quietThresholdMs);
}
/**
* Prefer a naturally quiet window, then briefly drain new inference traffic.
* Automatic supervisor refresh uses allowBusyDrain=false: it fences admission
* only after a quiet observation and never waits for busy workers behind it.
* Existing requests are never interrupted; a bounded drain failure is returned
* to the caller so admission can be reopened and retried later.
*/
export async function waitForProxyUpdateWindow(options) {
const now = options.now ?? Date.now;
const wait = options.sleep ??
((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
const quietDeadline = now() + options.quietWaitMs;
while (now() < quietDeadline) {
if (options.isStopping()) {
return { ready: false, draining: false, reason: "stopping" };
}
if (!options.isParentAlive()) {
return { ready: false, draining: false, reason: "parent_stopped" };
}
const activity = await options.getActivity();
if (activity && isQuiet(activity, options.quietThresholdMs, now())) {
if (options.allowBusyDrain !== false) {
return { ready: true, draining: false };
}
break;
}
options.onPhase?.("waiting_for_quiet", activity);
await wait(options.pollIntervalMs);
}
if (options.allowBusyDrain === false) {
if (options.isStopping()) {
return { ready: false, draining: false, reason: "stopping" };
}
if (!options.isParentAlive()) {
return { ready: false, draining: false, reason: "parent_stopped" };
}
const activity = await options.getActivity();
if (!activity || !isQuiet(activity, options.quietThresholdMs, now())) {
options.onPhase?.("waiting_for_quiet", activity);
return { ready: false, draining: false, reason: "busy" };
}
}
if (!(await options.setDraining(true))) {
// The control response may have been lost after the parent applied it.
// Treat state as unknown/draining so the caller always attempts resume.
return { ready: false, draining: true, reason: "drain_failed" };
}
if (options.allowBusyDrain === false) {
// The worker's idle fence closes the observation/admission race. Any new
// cross-generation activity means resume immediately, never hold a busy
// service behind maintenance responses for the normal drain timeout.
const activity = await options.getActivity();
if (activity && isProxyRuntimeSettled(activity)) {
return { ready: true, draining: true };
}
const resumed = await options.setDraining(false);
return { ready: false, draining: !resumed, reason: "busy" };
}
const drainDeadline = now() + options.drainWaitMs;
while (now() < drainDeadline) {
if (options.isStopping()) {
return { ready: false, draining: true, reason: "stopping" };
}
if (!options.isParentAlive()) {
return { ready: false, draining: true, reason: "parent_stopped" };
}
const activity = await options.getActivity();
options.onPhase?.("draining", activity);
if (activity && isProxyRuntimeSettled(activity)) {
return { ready: true, draining: true };
}
await wait(options.pollIntervalMs);
}
const activity = await options.getActivity();
options.onPhase?.("drain_timeout", activity);
return { ready: false, draining: true, reason: "drain_timeout" };
}
/** An asynchronous staging job must not publish after its service owner changes. */
export function isProxyUpdateOwnerCurrent(options) {
return (!options.stopping &&
options.parentStatus === "running" &&
options.runtimePid === options.parentPid &&
options.runtimeUpdaterPid === options.updaterPid);
}