node.jsmultithreadingpromisenode-worker-threads

NodeJS no code running after worker code finishes


I'm having an issue with my worker code, currently i have some code that scans through two database tables and finds some matches and then adds some data from one table to the other creating a new table. This is a large set of data so i'm using worker threads to speed this up.

This is all working fine however once the worker threads are complete no other code runs i've tried adding the function LogData everywhere i can and it will not run i've even add the console.log("Finished building merge table") and that doesn't run either. Even the parentResolve does happen as i don't see the console.log("parentResolve") message.

if anyone can help me I would really appreciate it.

const calculateFactorialwithWorker = async () => {

    const SCCM = await ProgramDev.find({ "program name": { $not: { $regex: ".*[(]KB*[)]*" } } }).limit(8000)
    const sccmLength = SCCM.length

    mongoose.connection.close()

    return new Promise(async (parentResolve, parentReject) => {
        const numbers = [...new Array(sccmLength)].map((_, i) => i);

        const segmentSize = Math.ceil(sccmLength / userCPUCount);
        const segments = [];

        for (let segmentIndex = 0; segmentIndex < userCPUCount; segmentIndex++) {
            const start = segmentIndex * segmentSize;
            const end = start + segmentSize;
            const segment = numbers.slice(start, end)
            segments.push(segment);
        }
        try {
            const results = await Promise.all(
                segments.map(
                    segment =>
                        new Promise((resolve, reject) => {
                            const worker = new Worker(workerPath, {
                                workerData: segment,
                            });
                            worker.on('message', resolve);
                            worker.on('error', reject);
                            worker.on('exit', (code) => {
                                if (code !== 0)
                                    reject(new Error(`Worker stopped with exit code ${code}`));
                            });
                        })
                ));

            parentResolve(() => {

                console.log("parentResolve")

            })
        } catch (e) {
            parentReject(e)
        }
    });
};

calculateFactorialwithWorker().then(() => {

    console.log("Finished building merge table")
    LogData
})

Solution

  • Add if else block in worker exit event. When exit fired with code === 0 , there is no resolve/reject to handle it. The promises will not be resolved/rejected.

    Ref. https://nodejs.org/api/worker_threads.html#worker_threads_event_exit

    Also, I rewrite your codes a bit because some promises wrapper is unnecessary.

    const calculateFactorialwithWorker = async () => {
      try {
        const SCCM = await ProgramDev.find({
          "program name": { $not: { $regex: ".*[(]KB*[)]*" } },
        }).limit(8000);
    
        const sccmLength = SCCM.length;
    
        const numbers = [...new Array(sccmLength)].map((_, i) => i);
    
        const segmentSize = Math.ceil(sccmLength / userCPUCount);
        const segments = [];
    
        for (let segmentIndex = 0; segmentIndex < userCPUCount; segmentIndex++) {
          const start = segmentIndex * segmentSize;
          const end = start + segmentSize;
          const segment = numbers.slice(start, end);
          segments.push(segment);
        }
    
        const promises = segments.map(
          segment =>
            new Promise((resolve, reject) => {
              const worker = new Worker(workerPath, {
                workerData: segment,
              });
              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 {
                  resolve();
                }
              });
            })
        );
    
        await Promise.all(promises);
      } catch (err) {
        throw new Error(err);
      }
    };
    
    calculateFactorialwithWorker()
      .then(() => {
        console.log("Finished building merge table");
        LogData();
      })
      .catch(console.log)
      .finally(() => {
        mongoose.connection.close();
      });