josdejong / workerpool

Offload tasks to a pool of workers on node.js and in the browser
Apache License 2.0
2.04k stars 148 forks source link

[help wanted] Additional functions in worker context #407

Closed ahoyahoy closed 9 months ago

ahoyahoy commented 10 months ago

Hi there :)

I'm trying to make a testing worker, but I can't give it context functions.

simple testing environment

function add(a, b) {
    return a + b;
}

const context = {
    addFn: add,
}

function evalInScope(js, contextAsScope) {
    const contextKeys = Object.keys(contextAsScope)
    const contextValues = contextKeys.map(key => contextAsScope[key])

    const functionBody = `
        const [${contextKeys}] = arguments;
        ${js}
    `
    const evalFn = new Function(functionBody)

    return evalFn.apply(null, contextValues)
}

function it(ctx, testName, testFuncStr) {
    try {
        const result = evalInScope(testFuncStr, ctx)
        return { status: 'passed', testName, result }
    } catch (error) {
        return { status: 'failed', testName, error: error.message }
    }
}

it works this way correctly it(context, 'test1', 'return addFn(3,2)')

but how to use aditional functions in worker?

pool.exec(it, [context, 'test 1', 'return addFn(3,2)'])
    .then(function (result) {
        console.log('result', result)
    })
    .catch(function (err) {
        console.error(err);
    })

returns an error

DOMException: Failed to execute 'postMessage' on 'Worker': function add(a, b) {
    return a + b;
} could not be cloned.

context functions are dynamic

Please advice how to do it :)

josdejong commented 10 months ago

You'll have to create a dedicated worker that has the functions it, evalInScope, etc. And you will somehow have to make the dedicated functions available inside this dedicated worker, for example by passing the path of the file where they are located and load that file inside the worker, or by sending over the code of the functions and evaluating this with eval inside the worker (though using eval is not a good idea in general).

ParishiB commented 9 months ago

@josdejong trying it your way