在node.js中最多分发并行REST调用/如何在node

时间:2018-08-29 12:31:55

标签: node.js async-await

我正在使用node.js,具有依赖的REST调用图,并试图并行分发它们。它是测试/负载测试脚本的一部分。

我的图具有“连接的组件”,并且每个组件都是有向的且无循环的。我对每个组件进行了分类,所以最终得到了一个像这样的图

Component1 = [Call1, Call2...., Callm] (Call2 possibly dependent on call1 etc)
Component2 = [Call1, Call2... Calln]
...
Componentp

组件的数量以及每个组件m,n和p中的调用都是动态的

我想对这些组件及其每个调用进行轮询,并发地最多分配“ x”个调用。

虽然我对Promises,async / await和Node的事件循环有所了解,但我不是专家。

仅伪代码

maxParallel = x
runningCallCount = 0
while(components.some(calls => calls.some(call => noResponseYet(call)) {
    if (runningCallCount < maxParallel) {
        runningCallCount++
        var result = await axios(call)
        runningCallCount--
    }
}

这不起作用-我从不派遣电话。 删除等待,然后我立即进入runningCallCount。

我尝试过的其他方法和评论

  • 将每个调用包装在一个异步函数中,并一次使用Promise.All来处理所有x值-一种方法的分块样式。这可能有效,但无法达到始终尝试进行x个并行调用的结果
    • 使用过的RxJ-尝试以最大并行度在所有组件上进行合并-但这使组件(而不是组件内的调用)并行化,我无法解决如何 根据可怜的doco使其以我想要的方式工作。我以前使用过.NET版本,所以这有点令人失望。
    • 我还没有尝试过递归

任何人都可以对如何做到这一点有所了解吗? 在节点中如何工作?我已经看到它像生成器函数和yield语句(https://medium.com/siliconwat/how-javascript-async-await-works-3cab4b7d21da)一样进行了解释 任何人都可以添加详细信息-当代码发出等待调用时如何检查事件循环?再一次,我猜是整个堆栈都展开了,或者是通过某种方式插入了运行事件循环的调用 等待呼叫。

我对使用负载测试包或其他负载测试工具不感兴趣-我只想了解执行此操作的最佳方法,还希望了解节点中的情况并等待。

如果我理解或找到解决方案,我会进行更新,但是

帮助表示赞赏。

1 个答案:

答案 0 :(得分:0)

我认为类似这样的方法可以实现始终进行n个并行调用。

const delay = time => new Promise(r=>setTimeout(r,time));

let maxJobs = 4;
let jobQueue = [
  {time:1000},{time:3000},{time:1000},{time:2000},
  {time:1000},{time:1000},{time:2000},{time:1000},
  {time:1000},{time:5000},{time:1000},{time:1000},
  {time:1000},{time:7000},{time:1000},{time:1000}
];
jobQueue.forEach((e,i)=>e.id=i);

const jobProcessor = async function(){
  while(jobQueue.length>0){
    let job = jobQueue.pop();
    console.log('Starting id',job.id);
    await delay(job.time);
    console.log('Finished id',job.id);
  }
  return;
};

(async ()=>{
  console.log("Starting",new Date());
  await Promise.all([...Array(maxJobs).keys()].map(e=>jobProcessor()))
  console.log("Finished",new Date());
})();