2

我正在使用worker_threadsvm2实现类似无服务器的东西,但是我无法在主线程中获取 NodeVM 实例,然后通过 workData(由于worker_threads的限制),所以我只能new NodeVM在每个请求的工作线程中,在其中我无法重用 vm 实例,成本会受到影响。

完成需要 200 ~ 450 ms ,new NodeVM()所以我希望预先初始化一个可重用的实例。

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,
  });

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

非常感谢。

4

1 回答 1

0

我决定禁止external模块导入。因为require在内部是readFileSync,大部分时间都是消耗的,而httpnode本身内部的模块可以用来替换request-promise.

注释掉external选项后,init 的平均时间成本大约是 10+ms,目前可以接受。

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

于 2019-01-17T15:51:40.200 回答