Вернувшись в исходную среду выполнения Lambda для Node.js 0.10, Lambda предоставила вспомогательные функции в объекте context
: context.done(err, res)
context.succeed(res)
и context.fail(err)
.
Это было ранее задокументировано, нобыл удален.
Использование более ранней версии Node.js v0.10.42 - это архивированная копия страницы, которой больше нет в документации Lambda, которая объясняет, как использовались эти методы.
Когда была запущена среда выполнения Node.js 4.3 для Lambda, они оставались для обратной совместимости (и остаются доступными, но не документированы), и была введена callback(err, res)
.
Вот характер вашей проблемы и почемудва решения, которые вы нашли, на самом деле, кажется, решают эту проблему.
Context.succeed, context.done и context.fail, однако, это больше, чем просто бухгалтерия - они заставляют запрос вернуться после завершения текущей задачии немедленно заморозить процесс, даже если другие задачи остаются в цикле событий Node.js.Как правило, это не то, что вам нужно, если эти задачи представляют неполные обратные вызовы.
https://aws.amazon.com/blogs/compute/node-js-4-3-2-runtime-now-available-on-lambda/
Так что с callback
функции Lambda теперь ведут себя более парадигматически корректно, но этопроблема, если вы намереваетесь оставить определенные объекты в цикле событий во время остановки, которая происходит между вызовами - в отличие от старых (устаревших) методов done
fail
succeed
, использование обратного вызова не приостанавливает работу сразу,Вместо этого он ожидает, что цикл событий будет пустым.
context.callbackWaitsForEmptyEventLoop
- по умолчанию true
- был введен, чтобы вы могли установить его на false
для этих случаевгде вы хотите, чтобы лямбда-функция возвращалась сразу после вызова обратного вызова, независимо от того, что происходит в цикле событий.По умолчанию это true
, потому что false
может маскировать ошибки в вашей функции и может привести к очень ошибочному / неожиданному поведению, если вы не учтете последствия повторного использования контейнера - поэтому вам не следует устанавливать это значение на false
, если и доВы понимаете, почему это необходимо.
Общая причина false
- подключение к базе данных, выполненное вашей функцией.Если вы создадите объект соединения с базой данных в глобальной переменной, он будет иметь открытый сокет и, возможно, другие вещи, такие как таймеры, сидящие в цикле событий.Это препятствует тому, чтобы обратный вызов заставлял Lambda возвращать ответ до тех пор, пока эти операции также не будут завершены или не сработает таймер тайм-аута вызова.
Укажите, почему необходимо установить это значение на false
, и если это является действительной причинойтогда правильно его использовать.
В противном случае в вашем коде может быть ошибка, которую вам необходимо понять и исправить, например, оставить запросы в полете или незавершенную работу при вызове обратного вызова.
Итак, как нам разобратьОшибка Cognito?Сначала это казалось довольно необычным, но теперь ясно, что это не так.
При выполнении функции Lambda выдаст ошибку, для которой задание истекло по истечении заданного количества секунд.Это должно произойти, когда вы тестируете свою функцию в консоли Lambda.
К сожалению, Cognito, по-видимому, использовал внутренний ярлык дизайна при вызове функции Lambda и вместо ожидания Lambda для тайм-аутаinvocarion (который может связать ресурсы внутри Cognito) или наложение собственного явного таймера на максимальную продолжительность, Cognito будет ожидать лямбда-ответа, он полагается на таймер сокета нижнего уровня, чтобы ограничить это ожидание ... таким образом, «неожиданная» ошибкаВыдается при вызове тайм-аута.
Более сложная интерпретация сообщения об ошибке: в ошибке отсутствуют кавычки, где интерполируется исключение нижнего уровня.
Для меня проблема была бы гораздо более сложнойочистить, если ошибка читается так:
'arn:aws:lambda:...' failed with error 'Socket timeout' while invoking Lambda function
Этот формат более четко указывал бы на то, что, когда Cognito вызывал функцию, он выдавал внутреннюю ошибку Socket timeout
(в отличие от Lambda с неожиданной внутренней ошибкой, которая была моейоригинальное - и неверное - предположение).
Вполне разумно, чтобы Cognito ввел какое-то ограничение по времени отклика для функции Lambda, но я не вижу этого документированным.Я подозреваю, что короткий тайм-аут на самой вашей функции Lambda (что приводит к более быстрому сбою) заставит Cognito выдать несколько более полезную ошибку, но, на мой взгляд, Cognito должен был быть разработан, чтобы включать логику, чтобы сделать эту ожидаемую, определенную ошибку,вместо того, чтобы классифицировать его как «неожиданный».