Главная проблема: Функция Lambda не завершается после успешного вызова внешнего API, что впоследствии вызывает несколько внешних вызовов API.
У меня есть лямбда-функция, которая прослушивает слабые события, когда происходит событие, когда вызывается лямбда-функция. Я фильтрую эти события, используя некоторые проверки условий, и когда происходит целевое событие, я делаю внешний вызов API.
Все вышеперечисленное работает, однако внешний вызов API запускается несколько раз для одного события (~ 4 раза, когда он должен быть 1 в случае успеха).
Идемпотент - Часто люди связывают эту проблему с идемпотентностью, однако, учитывая внешний вызов API в блоке условий, который запускается несколько раз, я не считаю это проблемой.
statusCode 200 перед последующими (дополнительными) внешними вызовами APIcontext.done() и лишние callback(), но не повезлоПоиск некоторых предлагаемых подходов
Я прикрепил лямбда-функцию ниже:
const axios = require('axios');
const sendMessages = async(event, context, callback) => {
// test the message for a match
if (event.type === 'message' && event.bot_id !== undefined) {
console.info("filter events for specific event");
let URL = 'https://someurl.com/slack/events';
let response = await axios.post(URL, {
events: event,
});
console.info("response success :: ", response.status);
if (response.status === 200) {
console.info("condition met");
context.done();
callback(null, 'successful request');
}
}
callback(null, 'successful request');
};
// Lambda handler
exports.server = (data, context, callback) => {
let eventData = JSON.parse(data.body);
switch (data.path) {
case "/slack-events": sendMessages(eventData.event, context, callback); break;
default: callback(null);
}
};
Ожидаемое поведение
@ThalesMinussi Вы можете нажать кнопку «Отзыв» на страницах документации, которые будут перенаправлены группам документации. Однако, если вы хотите написать более подробное объяснение, не стесняйтесь отправить его мне по электронной почте, и я подниму его вместе с командой документации. (Я не специалист по Node, поэтому было бы хорошо, если бы кто-то, знакомый с большинством проблем, задокументировал для них проблему.)
@JohnRotenstein Идеально. Я сделаю это, когда у меня будет свободное время, чтобы написать подробное объяснение. Спасибо, что нашли время, чтобы вернуться ко мне. Может быть, открыть исходный код документов было бы хорошей идеей...
@ThalesMinussi Документация AWS доступна на github, поэтому вы можете отправлять запросы на включение (но я не уверен, что там есть руководства по ВСЕ).
@JohnRotenstein github.com/awsdocs/aws-doc-sdk-examples/issues/754 Я уже сделал PR. Посмотрим, как вы, ребята из AWS, и сообщество отреагируете.

Проблема (вы не первый и не последний, кто задает этот тип вопроса, AWS необходимо исправить документы как можно скорее) заключается в том, что вы смешиваете async/await с вызовами context.done и callback().
Если ваши функции уже async, то придерживайтесь await до конца и забудьте о context и callback объектах.
Обратите внимание, что sendMessages — это async, поэтому он возвращает обещание, но вы ничего не делаете с этим обещанием. Вы должны await на нем. Я соответствующим образом изменил ваш код и избавился от объектов context и callback, они вам не нужны.
const axios = require('axios');
const sendMessages = async (event) => {
// test the message for a match
if (event.type === 'message' && event.bot_id !== undefined) {
console.info('filter events for specific event');
let URL = 'https://someurl.com/slack/events';
let response = await axios.post(URL, {
events: event,
});
console.info('response success :: ', response.status);
return response;
}
return Promise.resolve({});
};
// Lambda handler
exports.server = async (event) => {
let eventData = JSON.parse(event.body);
switch (event.path) {
case '/slack-events':
await sendMessages(eventData.event);
break;
}
return {
message: 'Success',
}
};
Если эта лямбда вызывается API-шлюзом, вам нужно вернуть код состояния 2xx (или 4xx и 5xx в случае ошибок) со строковым телом, чтобы оно могло завершиться правильно, например так:
return {
statusCode: 200,
body: JSON.stringify({message: 'Success'})
}
Спасибо за ответ. Это имеет смысл, и я соответствующим образом изменил лямбда-функцию, однако проблема не устранена. Теперь, когда я правильно ожидаю обещания sendMessages, должен ли я что-либо делать с ответом, чтобы завершить/выйти из функции в лямбда-обработчике?
Добро пожаловать. Не совсем... этот блок return { message: 'Success } должен справиться с этим. Если это не вызов из API-шлюза. Так ли это? Если это так, вам нужно добавить statusCode и преобразовать тело в строку. Я обновлю свой ответ.
@JohnRotenstein, не могли бы вы связаться с командой документации и узнать, могут ли они обновить документы? Однажды я связался с @SebastienStomarq, и он сказал, что уже разговаривал с командой документации, но до сих пор документы не были обновлены. Большинство вопросов, на которые мы получаем ответы на SO в эти дни, касаются
async/await, используемого в сочетании с вызовамиcontextиcallback, что создает абсолютный беспорядок. Эти вопросы будут продолжать поступать, если документы не будут исправлены.