У меня есть API загрузки POST /api/v1/upload
, где пользователи могут загружать текстовые файлы. Я использовал Node Formidable для анализа данных формы в Express, и все работает хорошо. Вот текущий код.
// app.js
...
const IncomingForm = require('formidable').IncomingForm;
app.post('/api/v1/upload', (req, res) => {
const form = new IncomingForm();
form.on('file', async (field, file) => {
// do something...
});
form.on('end', () => {
console.log('Done parsing.');
});
form.parse(req); // I believe this is the main function
})
...
Теперь я хочу делегировать эту операцию рабочему потоку.
// app.js
...
const usingWorkerThreads = require('./worker.js')
router.post('/api/v1/upload', (req, res) => {
const result = await usingWorkerThreads(req);
res.send(result);
});
...
А вот мой стандартный файл worker_thread
, довольно стандартный, взято с официального сайта node.js .
// worker.js
...
const IncomingForm = require('formidable').IncomingForm;
const {
Worker, isMainThread, parentPort, workerData
} = require('worker_threads');
if (isMainThread) {
module.exports = function parseJSAsync(script) {
return new Promise((resolve, reject) => {
const worker = new Worker(__filename, {
workerData: script
});
worker.on('message', resolve);
worker.on('error', reject);
worker.on('exit', (code) => {
if (code !== 0)
reject(new Error(`Worker stopped with exit code ${code}`));
});
});
};
} else {
// Form-parsing code, taken out from app.js and pasted here
const form = new IncomingForm();
form.on('file', async (field, file) => {
// do something...
});
form.on('end', () => {
parentPort.postMessage('Done parsing.')
});
form.parse(workerData);
}
...
Проблема в том, что объект req
нельзя передать из app.js
в worker.js
, а для библиотеки Formidable
требуется req
объект. Вот ошибка, которую я получаю.
(node:13024) UnhandledPromiseRejectionWarning: DataCloneError: function resetHeadersTimeoutOnReqEnd() {
debug('resetHeadersTimeoutOnReqEnd');
const parser = this.socket....<omitted>...
} could not be cloned.
at new Worker (internal/worker.js:305:17)
Похоже, что есть функция с именем resetHeadersTimeoutOnReqEnd()
где-то глубоко вложенная в объект req
, который не может быть клонирован при передаче в worker.js
. Даже если я вручную найду и удалю эту функцию из объекта req
, есть еще одна похожая функция, которая вызывает ту же проблему.