Отправка до максимум параллельных REST-вызовов в node.js / как ожидают работы в узле - PullRequest
0 голосов
/ 29 августа 2018

Я использую 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, я НЕ эксперт.

ТОЛЬКО КОД PSEUDO

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

Это не работает - я никогда не отправляю звонки. Удалите ожидание, и я проваливаюсь на бегущий вызов - сразу же.

Другие подходы, которые я пробовал и комментарии

  • Обтекание каждого вызова в асинхронной функции и использование Promise.All по фрагменту числа x за раз - подход разделения по частям. Это может сработать, но это не дает результата, когда все время пытаются выполнить x параллельных вызовов
    • Использовал RxJs - попытался объединить все компоненты с максимальным числом параллелизма - но это распараллеливает компоненты, а не вызовы внутри компонентов, и я не мог понять, как сделать так, как я хотел, на основе плохого доко. Раньше я пользовался версией .NET, так что это немного разочаровало.
    • я еще не пробовал рекурсию

Кто-нибудь может предложить идею, как это сделать? Как ждать работы в узле? Я видел, как это объясняется как функции генератора и операторы yield (https://medium.com/siliconwat/how-javascript-async-await-works-3cab4b7d21da) Кто-нибудь может добавить подробности - как проверяется цикл обработки событий, когда код выполняет ожидающий вызов? Снова я предполагаю, что либо весь стек разворачивается, либо вызов для запуска цикла обработки событий каким-то образом вставляется жду звонка.

Меня не интересует использование пакета нагрузочного тестирования или других инструментов нагрузочного тестирования - я просто хочу понять, как лучше всего это сделать, но также понимаю, что происходит в узле, и жду.

Я обновлю это, если пойму или найду решение, но

Помощь оценена.

1 Ответ

0 голосов
/ 29 августа 2018

Я бы подумал, что что-то подобное будет работать, чтобы всегда иметь 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());
})();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...