mongoose with worker-thread

Created on 2 May 2020  路  5Comments  路  Source: Automattic/mongoose

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
Screen Shot 2020-05-02 at 10 50 30 AM
Screen Shot 2020-05-02 at 10 50 42 AM
Screen Shot 2020-05-02 at 10 51 01 AM

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.

All 5 comments

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.

Was this page helpful?
0 / 5 - 0 ratings