openreader/packages/compute-worker/src/operations/state-machine.ts
Richard R 358a56cc9a refactor: implement modular monorepo packages
- Extract database schema and migrations into @openreader/database

- Extract startup and orchestration scripts into @openreader/bootstrap

- Move compute-worker into packages/compute-worker

- Remove runtime dependency on drizzle-kit

- Update Dockerfile to deploy isolated packages without merging node_modules
2026-06-13 13:51:18 -06:00

65 lines
2 KiB
TypeScript

import type {
WorkerJobErrorShape,
WorkerJobState,
WorkerOperationKind,
WorkerOperationRequest,
WorkerOperationState,
} from '../operations/contracts';
export function isTerminalStatus(status: WorkerJobState): boolean {
return status === 'succeeded' || status === 'failed';
}
export function isInflightStatus(status: WorkerJobState): boolean {
return status === 'queued' || status === 'running';
}
export function createErrorShape(error: unknown): WorkerJobErrorShape {
if (error && typeof error === 'object' && 'message' in error && typeof (error as { message: unknown }).message === 'string') {
return { message: (error as { message: string }).message };
}
return { message: String(error) };
}
export function buildQueuedState(input: {
request: WorkerOperationRequest;
opId: string;
jobId: string;
queuedAt: number;
}): WorkerOperationState {
return {
opId: input.opId,
opKey: input.request.opKey,
kind: input.request.kind,
jobId: input.jobId,
status: 'queued',
queuedAt: input.queuedAt,
updatedAt: input.queuedAt,
};
}
export function explainReplacementReason(input: {
current: WorkerOperationState;
requestKind: WorkerOperationKind;
now: number;
opStaleMs: number;
}): string {
if (input.current.kind !== input.requestKind) return 'kind_mismatch';
const ageMs = input.now - input.current.updatedAt;
if (isInflightStatus(input.current.status) && ageMs > input.opStaleMs) return 'stale_running';
if (input.current.status === 'failed') return 'failed_prior';
return `status_${input.current.status}`;
}
export function shouldReuseExistingOperation(input: {
current: WorkerOperationState;
requestKind: WorkerOperationKind;
now: number;
opStaleMs: number;
}): boolean {
if (input.current.kind !== input.requestKind) return false;
if (input.current.status === 'succeeded') return true;
if (!isInflightStatus(input.current.status)) return false;
const ageMs = input.now - input.current.updatedAt;
return ageMs <= input.opStaleMs;
}