在worker_threads中使用vm2时,是否可以在worker之间共享NodeVM实例?

时间:2019-01-17 04:49:47

标签: node.js node-vm2

我正在使用worker_threadsvm2来实现类似无服务器的功能,但是我无法在主线程中获取NodeVM实例,然后再通过workData(因为worker_threads'的限制),因此每个请求只能在一个工作线程中使用new NodeVM,在该线程中我无法重用vm实例,并且会降低成本。

new NodeVM()完成需要200到450毫秒,因此我希望预先初始化一个可重用的实例。

const w = new Worker(`
    (async () => {
      const { workerData, parentPort } = require('worker_threads');
      const { NodeVM } = require('vm2');
      const t = Date.now();
      const vm = new NodeVM({ // cost 200 ~ 450 ms
        console: 'inherit',
        require: {
          external: [ 'request-promise', 'lodash' ],
          builtin: [],
          import: [ 'request-promise', 'lodash' ], // faster if added
        },
      });
      console.log('time cost on new NodeVM:', Date.now() - t);
      const fnn = vm.run(workerData.code, workerData.filename);
      console.log('time cost by initializing vm:', Date.now() - t);
      try {
        const ret = await fnn(workerData.params);

        parentPort.postMessage({
          data: typeof ret === 'string' ? ret : JSON.stringify(ret),
        });
      } catch (e) {
        parentPort.postMessage({
          err: e.toString(),
        });
      }
      console.log('----worker donex');
    })();
  `,
  {
    workerData: {
      params,
      code,
      dirname: __dirname,
      filename: `${__dirname}/faasVirtual/${fn}.js`,
    },
    eval: true,
  });

有人可以给我一些建议吗?

非常感谢。

1 个答案:

答案 0 :(得分:0)

我已决定禁止导入external模块。因为require在内部是readFileSync,这花费了大部分时间,并且节点本身内的http模块可以用来替换request-promise

在注释掉external选项后,初始化的平均时间成本大约为10 + ms,目前可以接受。

但是如果worker_threads可以通过workerData克隆函数对象,则效率会更高。