vercel / pkg

Package your Node.js project into an executable
https://npmjs.com/pkg
MIT License
24.28k stars 1.01k forks source link

pkg with worker_threads #1993

Closed dmm-mkcvi closed 8 months ago

dmm-mkcvi commented 11 months ago

What version of pkg are you using?

5.8.1

What version of Node.js are you using?

18

What operating system are you using?

windows

What CPU architecture are you using?

x64

What Node versions, OSs and CPU architectures are you building for?

node18-win

Describe the Bug

node module not found

Expected Behavior

node module found when added as scripts

To Reproduce

cant share my code but you can reproduce with a simple example using worker_threads, const worker = new Worker(__filename);

xts-bit commented 11 months ago

@dmm-mkcvi did you fix?

dmm-mkcvi commented 11 months ago

I have a workaround, load the module as a file: var file = fs.readFileSync(filepath,{ encoding: 'utf8', flag: 'r' }); and using: new Worker(file ,{eval:true}); it will recognize the module, after, every require in the module not in node-modules should need to be passed as a script It is working in production using this method but encrypting the module file first and decrypting it in run time only to not let the module code be in plain text

xts-bit commented 11 months ago

@dmm-mkcvi Yep,

I'm getting this error now "Error: Runtime exited with error: exit status 1 Runtime.ExitError"

I'm doing like this

var file = fs.readFileSync("./worker.ts",{ encoding: 'utf8', flag: 'r' });
console.log(file)

    const worker = new Worker(file, {
        workerData: { taskId },
        eval: true
    });
dmm-mkcvi commented 11 months ago

can you give stacktrace?

xts-bit commented 11 months ago

@dmm-mkcvi how to get stack trace in nodejs vercel? i only get error on production (Vercel) This Serverless Function has crashed.

error like RequestId: 6304ca8a-256d-431a-91cf-8bc80718b875 Error: Runtime exited with error: exit status 1 Runtime.ExitError

dmm-mkcvi commented 11 months ago

i tried a simple test and it works fine index.ts: `const fs = require('fs'); var file = fs.readFileSync("./worker.ts",{ encoding: 'utf8', flag: 'r' }); const { Worker} = require('node:worker_threads');

function runService( worker) { return new Promise((resolve, reject) => { worker.on('message', resolve); worker.on('error', reject); worker.on('exit', (code) => { if (code !== 0) reject(new Error(Worker stopped with exit code ${code})); }) worker.postMessage({toworker:"run"}); })

}

async function run() { console.log(file) const worker = new Worker(file, { eval: true }); const result = await runService(worker) console.log(result); }

run().catch(err => console.error(err))`

worker.ts: const { parentPort } = require('node:worker_threads'); parentPort.on('message', (task) => { parentPort.postMessage( {success:'1'}); });

xts-bit commented 11 months ago

@dmm-mkcvi Thanks can you please check my question on StackOverflow i have some code there https://stackoverflow.com/questions/77167599/how-can-i-manage-lengthy-task-functions-in-node-js-express-js

I'm just trying execute function in the background

xts-bit commented 11 months ago

@dmm-mkcvi Hi can you please check my code?

import fs from 'fs'
import { v4 as uuidv4 } from 'uuid';
import { Worker } from 'node:worker_threads';

api.ts
router.post('/run-long-task', async (req, res) => {
    const taskId = uuidv4();

    const worker = new Worker(file, {
        workerData: { taskId },
        eval: true
    });

    tasksById.set(taskId, {
        status: 'running',
        started: Date.now(),
    });

    worker.on('message', async () => {
        try {
            tasksById.set(taskId, { status: 'completed' });
        } catch (error) {
            tasksById.set(taskId, { status: 'error', error: error.message });
        }
    });

    tasksById.set(taskId, {
        status: "running",
        started: Date.now(),
        worker,
    });

    worker.on("message", (status) => {
        tasksById.set(taskId, { status });
    });

    worker.on("error", (error) => {
        tasksById.set(taskId, { status: "error", error: error.message });
    });

    worker.on("exit", (code) => {
        if (code !== 0) {
            if (tasksById.get(taskId)?.status === "running") {
                tasksById.set(taskId, {
                    status: "error",
                    error: `Worker stopped with exit code ${code}`,
                });
            } else {

            }
        }
    });
    res.json({ taskId });
})

worker.ts:
import { parentPort } from "node:worker_threads";

async function performTask() {
    // Long Task Function 
 }

if (parentPort) {
    parentPort.on('message', (task) => {
        performTask()
        parentPort?.postMessage({ success: '1' });
    });
}
dmm-mkcvi commented 11 months ago

Try with only on worker.on("message") and with worker.postMessage({toworker:"run"});

`router.post('/run-long-task', async (req, res) => { const taskId = uuidv4();

const worker = new Worker(file, {
    workerData: { taskId },
    eval: true
});

tasksById.set(taskId, {
    status: 'running',
    started: Date.now(),
});
tasksById.set(taskId, {
    status: "running",
    started: Date.now(),
    worker,
});

worker.on("message", (status) => {
    tasksById.set(taskId, { status });
});

worker.on("error", (error) => {
    tasksById.set(taskId, { status: "error", error: error.message });
});

worker.on("exit", (code) => {
    if (code !== 0) {
        if (tasksById.get(taskId)?.status === "running") {
            tasksById.set(taskId, {
                status: "error",
                error: "Worker stopped with exit code ${code}",
            });
        } else {

        }
    }
});
worker.postMessage({toworker:"run"});
res.json({ taskId });

}`

xts-bit commented 11 months ago

@dmm-mkcvi Do you mean like this?


router.post('/run-long-task', async (req, res) => {
    const taskId = uuidv4();

    const worker = new Worker(file, {
        workerData: { taskId },
        eval: true
    });

    tasksById.set(taskId, {
        status: 'running',
        started: Date.now(),
    });
    tasksById.set(taskId, {
        status: "running",
        started: Date.now(),
        worker,
    });

    worker.postMessage({toworker:"run"});

    worker.on("message", (status) => {
        tasksById.set(taskId, { status });
    });

    worker.on("error", (error) => {
        tasksById.set(taskId, { status: "error", error: error.message });
    });

    worker.on("exit", (code) => {
        if (code !== 0) {
            if (tasksById.get(taskId)?.status === "running") {
                tasksById.set(taskId, {
                    status: "error",
                    error: "Worker stopped with exit code ${code}",
                });
            } else {

            }
        }
    });
    worker.postMessage({ toworker: "run" });
    res.json({ taskId });
})
xts-bit commented 11 months ago

@dmm-mkcvi Any idea about this?

xts-bit commented 11 months ago

@leo Can you please help?

github-actions[bot] commented 8 months ago

This issue is stale because it has been open 90 days with no activity. Remove the stale label or comment or this will be closed in 5 days. To ignore this issue entirely you can add the no-stale label

github-actions[bot] commented 8 months ago

This issue is now closed due to inactivity, you can of course reopen or reference this issue if you see fit.