122 lines
3.7 KiB
TypeScript
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,
|
|
};
|
|
}
|