UNPKG

@ywfe/cli

Version:

遥望前端开发命令行工具

73 lines (72 loc) 2.44 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const node_async_hooks_1 = require("node:async_hooks"); const node_events_1 = require("node:events"); const node_worker_threads_1 = require("node:worker_threads"); const path = require("path"); const kTaskInfo = Symbol('kTaskInfo'); const kWorkerFreedEvent = Symbol('kWorkerFreedEvent'); class WorkerPoolTaskInfo extends node_async_hooks_1.AsyncResource { constructor(callback) { super('WorkerPoolTaskInfo'); this.callback = callback; } done(err, result) { this.runInAsyncScope(this.callback, null, err, result); this.emitDestroy(); } } class WorkerPool extends node_events_1.EventEmitter { constructor(numThreads) { super(); this.numThreads = numThreads; this.workers = []; this.freeWorkers = []; this.tasks = []; for (let i = 0; i < numThreads; i++) { this.addNewWorker(); } this.on(kWorkerFreedEvent, () => { if (this.tasks.length > 0) { const { pageName, callback } = this.tasks.shift(); this.runTask(pageName, callback); } }); } addNewWorker() { const worker = new node_worker_threads_1.Worker(path.resolve(__dirname, 'task-processor.js')); worker.on('message', (result) => { worker[kTaskInfo].done(null, result); worker[kTaskInfo] = null; this.freeWorkers.push(worker); this.emit(kWorkerFreedEvent); }); worker.on('error', (err) => { if (worker[kTaskInfo]) { worker[kTaskInfo].done(err, null); } else { this.emit('error', err); } this.workers.splice(this.workers.indexOf(worker), 1); this.addNewWorker(); }); this.workers.push(worker); this.freeWorkers.push(worker); this.emit(kWorkerFreedEvent); } runTask(pageName, callback) { if (this.freeWorkers.length === 0) { this.tasks.push({ pageName, callback }); return; } const worker = this.freeWorkers.pop(); worker[kTaskInfo] = new WorkerPoolTaskInfo(callback); worker.postMessage(pageName); } close() { for (const worker of this.workers) worker.terminate(); } } exports.default = WorkerPool;