UNPKG

@nazaire/orchestra

Version:

A framework for distributing work over many machines, integrated with Node.js workers to utilise many threads per machine.

106 lines 3.32 kB
import { nanoid } from "nanoid"; import { MessageType } from "./Network/index.js"; import { NetworkClient } from "./Network/NetworkClient.js"; import { Transform } from "node:stream"; export class Client extends NetworkClient { workspace; constructor(network, workspace) { super("client_" + nanoid(), network); this.workspace = workspace; } /** * Add a job to the composer's queue * @param options * @returns */ async queue(options) { return await this.createJob(options); } /** * Add a job and bypass the queue, returns the result once the job is complete * @param options * @returns the result of the job */ async play(options, onData) { const job = await this.createJob(options, 1); if (onData) { const stream = await this.stream(job.id); stream.on("data", onData); } return this.getJobResultPromise(job.id); } /** * Return a promise that resolves with the job when it is complete * @param jobId * @returns */ async completion(jobId) { return this.getJobCompletedPromise(jobId); } /** * Return a promise that resolves with the result when the job is complete */ async result(jobId) { return this.getJobResultPromise(jobId); } async stream(jobId) { const stream = new Transform({ objectMode: true, transform: (chunk, encoding, callback) => { callback(null, chunk); }, }); const subscription = await this.network.subscribeData((message) => { if (message.type === MessageType.JOB_DATA && message.data.id === jobId) { stream.write(message.data.data); } }); stream.on("close", () => { subscription.unsubscribe(); }); this.getJobCompletedPromise(jobId).then(() => { stream.end(); }); return stream; } /** * Retrieve the current state of a job * @param id * @returns */ async getJob(id) { const message = this.createMessage({ type: MessageType.QUERY_JOBS, destination: "*", data: { id }, }); const response = await this.sendAndAwaitResponse(message, 1000); return response.data[0]; } async createJob(options, priority = 0) { const message = this.createMessage({ type: MessageType.CREATE_JOB, destination: "composer", data: { options, priority }, }); const response = await this.sendAndAwaitResponse(message, 1000); return response.data; } async getJobCompletedPromise(jobId) { const completedMessage = this.network.first((m) => m.type === MessageType.JOB_COMPLETED && m.data.id === jobId); return completedMessage.then((value) => value.data); } getJobResultPromise(jobId) { const completed = this.getJobCompletedPromise(jobId); return completed.then((job) => { if (job.error) { throw new Error(job.error); } else { return job.result; } }); } } //# sourceMappingURL=Client.js.map