redis-smq-common
Version:
Provides essential components and utilities shared across RedisSMQ packages.
96 lines • 3.99 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.WorkerLoader = void 0;
const runnable_worker_js_1 = require("../runnable-worker.js");
const index_js_1 = require("../../async/index.js");
const filesystem_js_1 = require("../../env/filesystem.js");
class WorkerLoader {
constructor(logger, filenamePattern, onWorkerError, workerManager) {
this.logger = logger.createLogger(this.constructor.name);
this.filenamePattern = filenamePattern;
this.onWorkerError = onWorkerError;
this.workerManager = workerManager;
}
createWorker(filename, payload) {
const worker = new runnable_worker_js_1.RunnableWorker(filename, payload, this.logger);
worker.removeAllListeners('worker.error');
worker.on('worker.error', (err) => {
this.onWorkerError(err, filename);
});
this.workerManager.addWorker(worker);
return worker;
}
loadFromDirectory(directory, payload, cb) {
(0, filesystem_js_1.findFilesByPattern)(directory, this.filenamePattern, (err, files) => {
if (err) {
this.logger.error(`Failed to read directory ${directory}: ${err.message}`, err);
cb(err);
return;
}
const workerFiles = files !== null && files !== void 0 ? files : [];
if (workerFiles.length === 0) {
this.logger.warn(`No ${this.filenamePattern} files found in ${directory}`);
cb();
return;
}
this.logger.debug(`Found ${workerFiles.length} worker files`);
this.createWorkersBatch(workerFiles, payload, cb);
});
}
createWorkersBatch(filepaths, payload, cb) {
const tempWorkers = [];
index_js_1.async.eachOf(filepaths, (filepath, index, done) => {
this.logger.debug(`Creating worker ${index + 1}/${filepaths.length}: ${filepath}`);
try {
const worker = new runnable_worker_js_1.RunnableWorker(filepath, payload, this.logger);
worker.on('worker.error', (err) => {
this.logger.debug(`Temporary worker error from ${filepath}: ${err.message}`);
});
tempWorkers.push(worker);
done();
}
catch (error) {
const err = error instanceof Error
? error
: new Error('Failed to create worker');
this.logger.error(`Failed to create worker from ${filepath}: ${err.message}`, err);
done(err);
}
}, (err) => {
if (err) {
this.logger.error(`Error creating workers: ${err.message}`, err);
this.cleanupTempWorkers(tempWorkers, () => cb(err));
return;
}
tempWorkers.forEach((worker) => {
worker.removeAllListeners('worker.error');
worker.on('worker.error', (err) => {
this.onWorkerError(err, worker.getWorkerFilename());
});
this.workerManager.addWorker(worker);
});
this.logger.debug(`Successfully created ${tempWorkers.length} workers`);
cb();
});
}
cleanupTempWorkers(workers, cb) {
if (workers.length === 0) {
cb();
return;
}
this.logger.debug(`Cleaning up ${workers.length} temporary workers...`);
index_js_1.async.each(workers, (worker, _, done) => {
worker.shutdown((err) => {
if (err) {
this.logger.warn(`Temp worker cleanup failed: ${err.message}`);
}
done();
});
}, () => {
this.logger.debug('Temporary workers cleaned up');
cb();
});
}
}
exports.WorkerLoader = WorkerLoader;
//# sourceMappingURL=worker-loader.js.map