AWS Lambda Promise.all никогда не возвращается или await не работает с ним

Итак, у меня есть код ниже. Когда я запускаю его локально, он работает, как ожидалось. Когда я публикую его в лямбде, он не может получить мои элементы S3. Я вижу, что обещания создаются для моего запроса, но return Promise.all(ps) никогда не возвращает ожидаемые значения. Я пытался изменить это несколькими способами, но всегда ничего не делал. Я обновил свой локальный env, чтобы он был таким же, как лямбда (узел 8.10 и aws-sdk 2.290.0), и по-прежнему он работает локально, но не при размещении.

Журналы cloudwatch показывают, что он закончился, не содержит ошибок и заканчивается через ~ 100 мс.

Я призываю взять 20 объектов из s3 размером 8k каждый; Я добавил перерыв, чтобы получить только 1 запись, и то же самое происходит ... ничего.

module.exports = async(messages) => {
  try {

    for (var rec of messages) {
      debug('rec',rec);
      let samples = await getRecordingPageSamples(rec.serialNumber,rec.recordingSet,rec.recording,rec.pages);
      //NEVER GETS HERE IN LAMBDA
      ...
    }
    //NEVER GETS HERE IN LAMBDA
    console.info('we are done here.');
  } catch (e) {
    console.info('unhandled',e);
  }
};

function getRecordingPageSamples(serialNumber,recordingSet,recording,pages){
  let ps = getObjectGenerator(pages.map(x=>[process.env.s3EeegPageBucket,genRecordingSamplePath(serialNumber,recordingSet,recording,x)]));
  ps = ps.map( p=> p.then(obj=>{
    console.info('done',obj[1]);
    return obj.slice(0,2).concat([obj[1].split(s.FILE_NAME_SEP)[2],obj[2].Body.toString()]);
  }));
  // here ps is an array of promises ps [ Promise { <pending> } ]
  return Promise.all(ps);
}

function getObjectGenerator(list){
  let ps = [];
  for (let x of list){
    //DOES GET HERE IN LAMBDA
    console.info('requesting obj',x);
    ps.push( getObject(x[0],x[1]));
  }
  return ps;
}

const getObject = (bucket,key) => {
  return s3.getObject({
    Bucket: bucket, // Assuming this is an environment variable...
    Key: key
  })
    .promise()
    .then(data=>{
      //NEVER GETS HERE IN LAMBDA
      console.info('got it',key);
      return [bucket,key,data];
    });

Проблема решена. Над этим модулем была еще одна функция-оболочка, которая была асинхронной функцией, но не использовала ключевое слово await. Ошибка новичка!

Правильно ли вы ждете функцию верхнего уровня от своей функции-обработчика лямбда?

Evert 11.12.2018 20:56

@Evert, ты мой герой GD ... Вот я пытаюсь повторно использовать код и пропускаю ожидание, пока содержащаяся функция была асинхронной. Ваше здоровье!

Robel Robel Lingstuyl 11.12.2018 21:45

Рад, что смог помочь! С чем-то я тоже столкнулся =) Наверное, помогает хороший способ запустить это на локальном компьютере. Делает более очевидным, когда заканчивается функция обработчика.

Evert 11.12.2018 22:01

Я запускаю его локально, но, похоже, на этом работа завершена. Я начал его отслеживать, потому что добавил больше журналов, показывающих, что finally было запущено до выполнения обещаний. Я предполагаю, что единственный способ сделать это локально подобным образом - создать другую оболочку, которая убивает процесс узла после возврата обработчика. Есть мысли о том, как это сделать?

Robel Robel Lingstuyl 11.12.2018 22:26

Я знаю, что есть инструменты, которые делают все это за вас, но я сделал это просто так, чтобы после возврата обработчика выходных данных было немного. process.exit() более агрессивен, но тоже может работать.

Evert 12.12.2018 17:52

Мне не нравится слишком много инструментов, но есть вещи, специально предназначенные для локального тестирования микросервисов.

Evert 12.12.2018 17:53
Сортировка hashmap по значениям
Сортировка hashmap по значениям
На Leetcode я решал задачу с хэшмапой и подумал, что мне нужно отсортировать хэшмапу по значениям.
0
6
1 121
1

Ответы 1

Проблема решена. Над этим модулем была еще одна функция-оболочка, которая была асинхронной функцией, но не использовала ключевое слово await. Ошибка новичка! Спасибо @Evert

Другие вопросы по теме