Files
suaveplan/packages/foundation/flow/queue-distribution/tests/helpers/fake-worker.ts
2026-05-27 23:47:53 +01:00

122 lines
3.7 KiB
TypeScript

import type { DistributedTask } from "../../src/task/task.js";
import {
type Worker,
type WorkerHealth,
type WorkerInfo,
WorkerStatus,
type WorkerStatusValue,
} from "../../src/worker/worker.js";
export interface FakeWorkerOptions {
id: string;
status?: WorkerStatusValue;
capacity?: number;
weight?: number;
activeTasks?: number;
type?: string;
canAccept?: boolean;
execute?: (task: DistributedTask, input: unknown) => Promise<unknown>;
getHealth?: () => Promise<WorkerHealth>;
start?: () => Promise<void>;
stop?: () => Promise<void>;
}
export function makeFakeWorker(options: FakeWorkerOptions): Worker {
const state = {
status: options.status ?? WorkerStatus.ONLINE,
activeTasks: options.activeTasks ?? 0,
capacity: options.capacity ?? 2,
weight: options.weight ?? 1,
};
const type = options.type ?? "fake";
const worker: Worker = {
id: options.id,
get capacity(): number {
return state.capacity;
},
set capacity(v: number) {
state.capacity = v;
},
get weight(): number {
return state.weight;
},
set weight(v: number) {
state.weight = v;
},
get status(): WorkerStatusValue {
return state.status;
},
set status(v: WorkerStatusValue) {
state.status = v;
},
get activeTasks(): number {
return state.activeTasks;
},
set activeTasks(v: number) {
state.activeTasks = v;
},
executeTask: async (task, input) =>
options.execute
? (options.execute(task, input as unknown) as never)
: (undefined as never),
getHealth: async () =>
options.getHealth
? options.getHealth()
: {
isHealthy:
state.status !== WorkerStatus.UNHEALTHY &&
state.status !== WorkerStatus.OFFLINE,
metrics: {
cpu: 0,
memory: 0,
tasksFailed: 0,
tasksSucceeded: 0,
responseTime: 0,
},
},
start: async () => {
if (options.start) await options.start();
state.status = WorkerStatus.ONLINE;
},
stop: async () => {
if (options.stop) await options.stop();
state.status = WorkerStatus.OFFLINE;
},
canAcceptTask: () =>
options.canAccept !== undefined
? options.canAccept
: (state.status === WorkerStatus.ONLINE ||
state.status === WorkerStatus.BUSY) &&
state.activeTasks < state.capacity,
getInfo: (): WorkerInfo => ({
id: options.id,
name: options.id,
type,
capacity: state.capacity,
weight: state.weight,
status: state.status,
activeTasks: state.activeTasks,
}),
};
return worker;
}
export function makeFakeTask<I = unknown, O = unknown>(
id: string,
execute?: (input: I) => Promise<O>
): DistributedTask<I, O> {
const status = "PENDING" as const;
let s: string = status;
const metadata = { createdAt: new Date(0), attempts: 0 };
return {
id,
execute: async (input) =>
execute ? execute(input) : (undefined as unknown as O),
getStatus: () => s as never,
setStatus: (newStatus) => {
s = newStatus;
},
getMetadata: () => metadata,
};
}