Home > Blockchain >  Timeout option is not working in nodejs spawn child process
Timeout option is not working in nodejs spawn child process

Time:07-03

I was trying to run the Python program through spawn child process function and trying to give timeout option for TLE cases. But Timeout option is not working. Code is running fine for smaller inputs, but when running on input size > 1e9 it should terminate in 5 seconds according to my code. But when sending request it gets hanging around infinitely.

My Nodejs code

        let python = spawn('python3', [`./uploads/${codefile}`], { timeout: 5000 });

        python.stdout.on('data', (data) => {
            res.status(200).json({ Success: data.toString() });
            deleteFiles(req.files)
            return;
        });

        python.stderr.on('data', (data) => {
            res.status(200).json({ Error: data.toString() });
            deleteFiles(req.files)
            return;
        });

        python.on('error', (err) => {
            // will handle Sigterm signal here
            //  res.status(200).json({
            //      errorMessage: "Time Limit Exceeded, Please Optimised Your Code",
            //      errorType: "Time Limit Exceeded"
            //  });
            console.log(err)
            res.status(500).send("Internal Server Error");
            deleteFiles(req.files);
            return;
        });

My Python code

n=10000000000
b=0;
for i in range(n):
    b =1
print("calculated sum is",b)

I have also tried exec function with timeout option and it is working fine there but due to security reasons I do not wan't to use it. I am using Node.js version 16.15.1

CodePudding user response:

Uh, if the timeout in spawn isn't working.. you can use setTimeout logic to kill the program that would have its Time Limit Exceeded

        let python = spawn('python3', [`./uploads/${codefile}`]);
        let timeout=setTimeout(()=>{
            python.kill() //kills the program that is taking too long
            deleteFiles(req.files)
            res.status(200).json({
                errorMessage: "Time Limit Exceeded, Please Optimised Your Code",
                errorType: "Time Limit Exceeded"
            });
        },5000)
        
        //I'd add a "python.on('end',some_callback)" but you seem to return the response on one chunk of data
        python.stdout.on('data', (data) => {
            res.status(200).json({ Success: data.toString() });
            deleteFiles(req.files)
            clearTimeout(timeout) //preventing the timeout from calling since it didn't take too long
            return;
        });

        python.stderr.on('data', (data) => {
            res.status(200).json({ Error: data.toString() });
            deleteFiles(req.files)
            clearTimeout(timeout) //preventing the timeout from calling since it didn't take too long
            return;
        });

        python.on('error', (err) => {
            // will handle Sigterm signal here
            //  res.status(200).json({
            //      errorMessage: "Time Limit Exceeded, Please Optimised Your Code",
            //      errorType: "Time Limit Exceeded"
            //  });
            console.log(err)
            clearTimeout(timeout) //preventing the timeout from calling since it didn't take too long
            res.status(500).send("Internal Server Error");
            deleteFiles(req.files);
            return;
        });
  • Related