3

I am trying to execute the following AWS lambda:

index.js:

const test = require("test");

exports.handler = async (event) => {
await test.main();

};

test.js:

const {Worker} = require("worker_threads");

const main = () => {
     
    let num1 = 10;
    let num2 = 20;
    
    const worker = new Worker("./worker.js", {workerData: {num1, num2}});
    
    worker.on("message", result => {
        console.log(`${num1} + ${num2} is ${result}`);
    });
    
    worker.on("error", error => {
        console.log(error);
    });
    
    worker.on("exit", exitCode => {
        console.log(exitCode);
    });
    
    console.log("I am here!");
}

exports.main = main;

worker.js:

const {parentPort, workerData} = require("worker_threads");

const getSum = (num1, num2) => {
    return num1 + num2;
}


parentPort.postMessage(getSum(workerData.num1, workerData.num2));

When I run the same program on my laptop it is working fine. I see the output of the worker thread consistently.

Output on my laptop:

❯ node index.js
I am here!
10 + 20 is 30
0

Output on the lambda:

START RequestId: c178d74b-da57-4765-9fa7-77d3fc83d645 Version: $LATEST
2021-08-31T14:33:37.353Z    c178d74b-da57-4765-9fa7-77d3fc83d645    INFO    I am here!
END RequestId: c178d74b-da57-4765-9fa7-77d3fc83d645
REPORT RequestId: c178d74b-da57-4765-9fa7-77d3fc83d645  Duration: 2.12 ms   Billed Duration: 3 ms   Memory Size: 10240 MB   Max Memory Used: 108 MB

When I run the lambda, the output is very random. Sometimes I see the output of the worker thread and other times I don't.

Why is there a difference in execution of the program on AWS lambda and on my laptop?

1 Answers1

3

You don't await for the worker async operation to complete in the test.js file. Try adding a promise that resolves when worker finishes. Like this:

const { Worker } = require("worker_threads");

const main = async () => {
  let num1 = 10;
  let num2 = 20;

  const worker = new Worker("./worker.js", { workerData: { num1, num2 } });

  worker.on("message", (result) => {
    console.log(`${num1} + ${num2} is ${result}`);
  });

  worker.on("error", (error) => {
    console.log(error);
  });

  console.log("I am here!");

  // Awaiting for the worker to finish here
  return new Promise((resolve) => {
    worker.on("exit", (exitCode) => {
      console.log(exitCode);
      resolve();
    });
  });
};

exports.main = main;

Alternatively, you can set context.doNotWaitForEmptyEventLoop = false but it's not recommended as it's error-prone and hard to debug.

Vlad Holubiev
  • 4,876
  • 7
  • 44
  • 59