node.js - 12.15.0
mongodb - 4.2.1
mongoose - ^5.9.11
I want to save data in worker thread, but I can't. It doesn't throw any error. Just code stop going forward. I use 3 files main.js, child.js, user-model.js
const { Worker } = require('worker_threads');
const cpuCount = require('os').cpus().length; // 8
const path = require('path');
const childWorkerPath = path.resolve(process.cwd(), 'child.js');
function putSegmentsInPromise(segments, childWorkerPath, data = {}) {
return segments.map(
segment => new Promise((resolve, reject) => {
const worker = new Worker(childWorkerPath, {
workerData: { segment, ...data }
});
worker.on('message', resolve);
worker.on('error', reject);
worker.on('exit', (code) => {
if (code !== 0) {
reject(new Error(Worker stopped with exit code ${code}
));
}
});
})
);
}
function breakSegments(arr, cpuCount) {
const segmentSize = Math.ceil(arr.length / cpuCount);
const segments = [];
for (let i = 0; i < cpuCount; i++) {
const start = i * segmentSize;
const end = start + segmentSize;
segments.push(arr.slice(start, end));
}
return segments;
}
const savingData = [
{ name: 'Ivetta', age: 28 },
{ name: 'Lizetta', age: 18 },
{ name: 'Myuzetta', age: 20 },
{ name: 'Zhanetta', age: 22 },
{ name: 'Zhorzhetta', age: 24 }
];
const segments = breakSegments(savingData, cpuCount);
putSegmentsInPromise(segments, childWorkerPath);
const { parentPort, workerData } = require('worker_threads');
const User = require('./data/models/user-model');
async function saveData(segments) {
try {
console.log('before create');
const arr = segments.map(item => ({
updateMany: {
filter: { age: item.age }, // find criteria
update: item, // change data
setDefaultsOnInsert: true,
upsert: true,
}
}));
const data = await User.bulkWrite(arr);
console.log({ data });
} catch (e) {
console.log({ e });
}
}
let result;
// result = saveData(workerData.segment);
// parentPort.postMessage(result);
(async () => {
result = await saveData(workerData.segment);
parentPort.postMessage(result);
})();
'use strict';
const mongoose = require('mongoose');
const { Schema } = mongoose;
const userSchema = new Schema({
name: {
type: String,
required: true
},
age: {
type: Number,
required: true
},
gender: {
type: String,
required: true,
default: null
},
created: {
type: Date,
default: Date.now
},
updated: {
type: Date,
default: Date.now
}
});
module.exports = mongoose.model('User', userSchema);
the worker thread has a different event loop so you will have to call mongoose.connect in your thread and I would also close it after.
are you sure you even need a worker thread? unless you are planning to do long data processing the time to takes to spin up the thread is probably not worth it.
@vorticalbox is right, you would need to call mongoose.connect()
in your worker thread.
Most helpful comment
the worker thread has a different event loop so you will have to call mongoose.connect in your thread and I would also close it after.
are you sure you even need a worker thread? unless you are planning to do long data processing the time to takes to spin up the thread is probably not worth it.